# HG changeset patch # User Juergen Gross # Date 1306494655 -7200 # Node ID eb601128d8930496007695233022b904fc62e039 # Parent 88fe9f780b3d0cf0fcd5aa9b87d4ec7ad404e985 use per-cpu variables in cpufreq The cpufreq driver used some local arrays indexed by cpu number. This patch replaces those arrays by per-cpu variables. The AMD and INTEL specific parts used different per-cpu data structures with nearly identical semantics. Fold the two structures into one by adding a generic architecture data item. Signed-off-by: juergen.gross@xxxxxxxxxxxxxx diff -r 88fe9f780b3d -r eb601128d893 xen/arch/x86/acpi/cpufreq/cpufreq.c --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Thu May 26 17:16:47 2011 +0100 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Fri May 27 13:10:55 2011 +0200 @@ -54,7 +54,7 @@ enum { #define INTEL_MSR_RANGE (0xffffull) #define CPUID_6_ECX_APERFMPERF_CAPABILITY (0x1) -static struct acpi_cpufreq_data *drv_data[NR_CPUS]; +DEFINE_PER_CPU(struct acpi_cpufreq_data *, cpufreq_data); static struct cpufreq_driver acpi_cpufreq_driver; @@ -103,7 +103,7 @@ static unsigned extract_msr(u32 msr, str static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data) { - switch (data->cpu_feature) { + switch (data->arch_cpu_flags) { case SYSTEM_INTEL_MSR_CAPABLE: return extract_msr(val, data); case SYSTEM_IO_CAPABLE: @@ -213,17 +213,17 @@ static u32 get_cur_val(const cpumask_t * return 0; policy = per_cpu(cpufreq_cpu_policy, cpu); - if (!policy || !drv_data[policy->cpu]) + if (!policy || !per_cpu(cpufreq_data, policy->cpu)) return 0; - switch (drv_data[policy->cpu]->cpu_feature) { + switch (per_cpu(cpufreq_data, policy->cpu)->arch_cpu_flags) { case SYSTEM_INTEL_MSR_CAPABLE: cmd.type = SYSTEM_INTEL_MSR_CAPABLE; cmd.addr.msr.reg = MSR_IA32_PERF_STATUS; break; case SYSTEM_IO_CAPABLE: cmd.type = SYSTEM_IO_CAPABLE; - perf = drv_data[policy->cpu]->acpi_data; + perf = per_cpu(cpufreq_data, policy->cpu)->acpi_data; cmd.addr.io.port = perf->control_register.address; cmd.addr.io.bit_width = perf->control_register.bit_width; break; @@ -372,7 +372,7 @@ static unsigned int get_cur_freq_on_cpu( if (!policy) return 0; - data = drv_data[policy->cpu]; + data = per_cpu(cpufreq_data, policy->cpu); if (unlikely(data == NULL || data->acpi_data == NULL || data->freq_table == NULL)) return 0; @@ -419,7 +419,7 @@ static int acpi_cpufreq_target(struct cp static int acpi_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - struct acpi_cpufreq_data *data = drv_data[policy->cpu]; + struct acpi_cpufreq_data *data = per_cpu(cpufreq_data, policy->cpu); struct processor_performance *perf; struct cpufreq_freqs freqs; cpumask_t online_policy_cpus; @@ -456,7 +456,7 @@ static int acpi_cpufreq_target(struct cp return 0; } - switch (data->cpu_feature) { + switch (data->arch_cpu_flags) { case SYSTEM_INTEL_MSR_CAPABLE: cmd.type = SYSTEM_INTEL_MSR_CAPABLE; cmd.addr.msr.reg = MSR_IA32_PERF_CTL; @@ -501,11 +501,11 @@ static int acpi_cpufreq_verify(struct cp struct acpi_cpufreq_data *data; struct processor_performance *perf; - if (!policy || !(data = drv_data[policy->cpu]) || - !processor_pminfo[policy->cpu]) + if (!policy || !(data = per_cpu(cpufreq_data, policy->cpu)) || + !per_cpu(processor_pminfo, policy->cpu)) return -EINVAL; - perf = &processor_pminfo[policy->cpu]->perf; + perf = &per_cpu(processor_pminfo, policy->cpu)->perf; cpufreq_verify_within_limits(policy, 0, perf->states[perf->platform_limit].core_frequency * 1000); @@ -557,9 +557,9 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol return -ENOMEM; memset(data, 0, sizeof(struct acpi_cpufreq_data)); - drv_data[cpu] = data; + per_cpu(cpufreq_data, cpu) = data; - data->acpi_data = &processor_pminfo[cpu]->perf; + data->acpi_data = &per_cpu(processor_pminfo, cpu)->perf; perf = data->acpi_data; policy->shared_type = perf->shared_type; @@ -569,7 +569,7 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol if (cpufreq_verbose) printk("xen_pminfo: @acpi_cpufreq_cpu_init," "SYSTEM IO addr space\n"); - data->cpu_feature = SYSTEM_IO_CAPABLE; + data->arch_cpu_flags = SYSTEM_IO_CAPABLE; break; case ACPI_ADR_SPACE_FIXED_HARDWARE: if (cpufreq_verbose) @@ -579,7 +579,7 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol result = -ENODEV; goto err_unreg; } - data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE; + data->arch_cpu_flags = SYSTEM_INTEL_MSR_CAPABLE; break; default: result = -ENODEV; @@ -652,17 +652,17 @@ err_freqfree: xfree(data->freq_table); err_unreg: xfree(data); - drv_data[cpu] = NULL; + per_cpu(cpufreq_data, cpu) = NULL; return result; } static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) { - struct acpi_cpufreq_data *data = drv_data[policy->cpu]; + struct acpi_cpufreq_data *data = per_cpu(cpufreq_data, policy->cpu); if (data) { - drv_data[policy->cpu] = NULL; + per_cpu(cpufreq_data, policy->cpu) = NULL; xfree(data->freq_table); xfree(data); } diff -r 88fe9f780b3d -r eb601128d893 xen/arch/x86/acpi/cpufreq/powernow.c --- a/xen/arch/x86/acpi/cpufreq/powernow.c Thu May 26 17:16:47 2011 +0100 +++ b/xen/arch/x86/acpi/cpufreq/powernow.c Fri May 27 13:10:55 2011 +0200 @@ -53,15 +53,7 @@ #define MSR_PSTATE_CUR_LIMIT 0xc0010061 /* pstate current limit MSR */ #define MSR_HWCR_CPBDIS_MASK 0x02000000ULL -struct powernow_cpufreq_data { - struct processor_performance *acpi_data; - struct cpufreq_frequency_table *freq_table; - unsigned int max_freq; - unsigned int resume; - unsigned int cpu_feature; -}; - -static struct powernow_cpufreq_data *drv_data[NR_CPUS]; +#define ARCH_CPU_FLAG_RESUME 1 static struct cpufreq_driver powernow_cpufreq_driver; @@ -92,7 +84,7 @@ static int powernow_cpufreq_target(struc static int powernow_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - struct powernow_cpufreq_data *data = drv_data[policy->cpu]; + struct acpi_cpufreq_data *data = per_cpu(cpufreq_data, policy->cpu); struct processor_performance *perf; struct cpufreq_freqs freqs; cpumask_t online_policy_cpus; @@ -119,8 +111,8 @@ static int powernow_cpufreq_target(struc next_perf_state = data->freq_table[next_state].index; if (perf->state == next_perf_state) { - if (unlikely(data->resume)) - data->resume = 0; + if (unlikely(data->arch_cpu_flags & ARCH_CPU_FLAG_RESUME)) + data->arch_cpu_flags &= ~ARCH_CPU_FLAG_RESUME; else return 0; } @@ -149,14 +141,14 @@ static int powernow_cpufreq_target(struc static int powernow_cpufreq_verify(struct cpufreq_policy *policy) { - struct powernow_cpufreq_data *data; + struct acpi_cpufreq_data *data; struct processor_performance *perf; - if (!policy || !(data = drv_data[policy->cpu]) || - !processor_pminfo[policy->cpu]) + if (!policy || !(data = per_cpu(cpufreq_data, policy->cpu)) || + !per_cpu(processor_pminfo, policy->cpu)) return -EINVAL; - perf = &processor_pminfo[policy->cpu]->perf; + perf = &per_cpu(processor_pminfo, policy->cpu)->perf; cpufreq_verify_within_limits(policy, 0, perf->states[perf->platform_limit].core_frequency * 1000); @@ -190,21 +182,21 @@ static int powernow_cpufreq_cpu_init(str unsigned int i; unsigned int valid_states = 0; unsigned int cpu = policy->cpu; - struct powernow_cpufreq_data *data; + struct acpi_cpufreq_data *data; unsigned int result = 0; struct processor_performance *perf; u32 max_hw_pstate; uint64_t msr_content; struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; - data = xmalloc(struct powernow_cpufreq_data); + data = xmalloc(struct acpi_cpufreq_data); if (!data) return -ENOMEM; - memset(data, 0, sizeof(struct powernow_cpufreq_data)); + memset(data, 0, sizeof(struct acpi_cpufreq_data)); - drv_data[cpu] = data; + per_cpu(cpufreq_data, cpu) = data; - data->acpi_data = &processor_pminfo[cpu]->perf; + data->acpi_data = &per_cpu(processor_pminfo, cpu)->perf; perf = data->acpi_data; policy->shared_type = perf->shared_type; @@ -252,7 +244,6 @@ static int powernow_cpufreq_cpu_init(str policy->governor = cpufreq_opt_governor ? : CPUFREQ_DEFAULT_GOVERNOR; - data->max_freq = perf->states[0].core_frequency * 1000; /* table init */ for (i = 0; i < perf->state_count && i <= max_hw_pstate; i++) { if (i > 0 && perf->states[i].core_frequency >= @@ -278,7 +269,7 @@ static int powernow_cpufreq_cpu_init(str * the first call to ->target() should result in us actually * writing something to the appropriate registers. */ - data->resume = 1; + data->arch_cpu_flags |= ARCH_CPU_FLAG_RESUME; policy->cur = data->freq_table[i].frequency; return result; @@ -287,17 +278,17 @@ err_freqfree: xfree(data->freq_table); err_unreg: xfree(data); - drv_data[cpu] = NULL; + per_cpu(cpufreq_data, cpu) = NULL; return result; } static int powernow_cpufreq_cpu_exit(struct cpufreq_policy *policy) { - struct powernow_cpufreq_data *data = drv_data[policy->cpu]; + struct acpi_cpufreq_data *data = per_cpu(cpufreq_data, policy->cpu); if (data) { - drv_data[policy->cpu] = NULL; + per_cpu(cpufreq_data, policy->cpu) = NULL; xfree(data->freq_table); xfree(data); } diff -r 88fe9f780b3d -r eb601128d893 xen/drivers/acpi/pmstat.c --- a/xen/drivers/acpi/pmstat.c Thu May 26 17:16:47 2011 +0100 +++ b/xen/drivers/acpi/pmstat.c Fri May 27 13:10:55 2011 +0200 @@ -57,7 +57,7 @@ int do_get_pm_info(struct xen_sysctl_get if ( !op || (op->cpuid >= NR_CPUS) || !cpu_online(op->cpuid) ) return -EINVAL; - pmpt = processor_pminfo[op->cpuid]; + pmpt = per_cpu(processor_pminfo, op->cpuid); switch ( op->type & PMSTAT_CATEGORY_MASK ) { @@ -203,7 +203,7 @@ static int get_cpufreq_para(struct xen_s if ( !op || !cpu_online(op->cpuid) ) return -EINVAL; - pmpt = processor_pminfo[op->cpuid]; + pmpt = per_cpu(processor_pminfo, op->cpuid); policy = per_cpu(cpufreq_cpu_policy, op->cpuid); if ( !pmpt || !pmpt->perf.states || @@ -426,7 +426,7 @@ int do_pm_op(struct xen_sysctl_pm_op *op if ( !op || !cpu_online(op->cpuid) ) return -EINVAL; - pmpt = processor_pminfo[op->cpuid]; + pmpt = per_cpu(processor_pminfo, op->cpuid); switch ( op->cmd & PM_PARA_CATEGORY_MASK ) { diff -r 88fe9f780b3d -r eb601128d893 xen/drivers/cpufreq/cpufreq.c --- a/xen/drivers/cpufreq/cpufreq.c Thu May 26 17:16:47 2011 +0100 +++ b/xen/drivers/cpufreq/cpufreq.c Fri May 27 13:10:55 2011 +0200 @@ -91,12 +91,12 @@ int __init cpufreq_register_governor(str int cpufreq_limit_change(unsigned int cpu) { - struct processor_performance *perf = &processor_pminfo[cpu]->perf; + struct processor_performance *perf = &per_cpu(processor_pminfo, cpu)->perf; struct cpufreq_policy *data; struct cpufreq_policy policy; if (!cpu_online(cpu) || !(data = per_cpu(cpufreq_cpu_policy, cpu)) || - !processor_pminfo[cpu]) + !per_cpu(processor_pminfo, cpu)) return -ENODEV; if (perf->platform_limit >= perf->state_count) @@ -120,10 +120,10 @@ int cpufreq_add_cpu(unsigned int cpu) struct cpufreq_dom *cpufreq_dom = NULL; struct cpufreq_policy new_policy; struct cpufreq_policy *policy; - struct processor_performance *perf = &processor_pminfo[cpu]->perf; + struct processor_performance *perf = &per_cpu(processor_pminfo, cpu)->perf; /* to protect the case when Px was not controlled by xen */ - if (!processor_pminfo[cpu] || + if (!per_cpu(processor_pminfo, cpu) || !(perf->init & XEN_PX_INIT) || !cpu_online(cpu)) return -EINVAL; @@ -159,17 +159,17 @@ int cpufreq_add_cpu(unsigned int cpu) /* domain sanity check under whatever coordination type */ firstcpu = first_cpu(cpufreq_dom->map); if ((perf->domain_info.coord_type != - processor_pminfo[firstcpu]->perf.domain_info.coord_type) || + per_cpu(processor_pminfo, firstcpu)->perf.domain_info.coord_type) || (perf->domain_info.num_processors != - processor_pminfo[firstcpu]->perf.domain_info.num_processors)) { + per_cpu(processor_pminfo, firstcpu)->perf.domain_info.num_processors)) { printk(KERN_WARNING "cpufreq fail to add CPU%d:" "incorrect _PSD(%"PRIu64":%"PRIu64"), " "expect(%"PRIu64"/%"PRIu64")\n", cpu, perf->domain_info.coord_type, perf->domain_info.num_processors, - processor_pminfo[firstcpu]->perf.domain_info.coord_type, - processor_pminfo[firstcpu]->perf.domain_info.num_processors + per_cpu(processor_pminfo, firstcpu)->perf.domain_info.coord_type, + per_cpu(processor_pminfo, firstcpu)->perf.domain_info.num_processors ); return -EINVAL; } @@ -261,10 +261,10 @@ int cpufreq_del_cpu(unsigned int cpu) struct list_head *pos; struct cpufreq_dom *cpufreq_dom = NULL; struct cpufreq_policy *policy; - struct processor_performance *perf = &processor_pminfo[cpu]->perf; + struct processor_performance *perf = &per_cpu(processor_pminfo, cpu)->perf; /* to protect the case when Px was not controlled by xen */ - if (!processor_pminfo[cpu] || + if (!per_cpu(processor_pminfo, cpu) || !(perf->init & XEN_PX_INIT) || !cpu_online(cpu)) return -EINVAL; @@ -371,7 +371,7 @@ int set_px_pminfo(uint32_t acpi_id, stru printk("Set CPU acpi_id(%d) cpuid(%d) Px State info:\n", acpi_id, cpuid); - pmpt = processor_pminfo[cpuid]; + pmpt = per_cpu(processor_pminfo, cpuid); if ( !pmpt ) { pmpt = xmalloc(struct processor_pminfo); @@ -381,7 +381,7 @@ int set_px_pminfo(uint32_t acpi_id, stru goto out; } memset(pmpt, 0, sizeof(*pmpt)); - processor_pminfo[cpuid] = pmpt; + per_cpu(processor_pminfo, cpuid) = pmpt; } pxpt = &pmpt->perf; pmpt->acpi_id = acpi_id; diff -r 88fe9f780b3d -r eb601128d893 xen/drivers/cpufreq/cpufreq_ondemand.c --- a/xen/drivers/cpufreq/cpufreq_ondemand.c Thu May 26 17:16:47 2011 +0100 +++ b/xen/drivers/cpufreq/cpufreq_ondemand.c Fri May 27 13:10:55 2011 +0200 @@ -194,7 +194,7 @@ static void dbs_timer_init(struct cpu_db set_timer(&per_cpu(dbs_timer, dbs_info->cpu), NOW()+dbs_tuners_ins.sampling_rate); - if ( processor_pminfo[dbs_info->cpu]->perf.shared_type + if ( per_cpu(processor_pminfo, dbs_info->cpu)->perf.shared_type == CPUFREQ_SHARED_TYPE_HW ) { dbs_info->stoppable = 1; diff -r 88fe9f780b3d -r eb601128d893 xen/drivers/cpufreq/utility.c --- a/xen/drivers/cpufreq/utility.c Thu May 26 17:16:47 2011 +0100 +++ b/xen/drivers/cpufreq/utility.c Fri May 27 13:10:55 2011 +0200 @@ -33,7 +33,7 @@ #include struct cpufreq_driver *cpufreq_driver; -struct processor_pminfo *__read_mostly processor_pminfo[NR_CPUS]; +DEFINE_PER_CPU_READ_MOSTLY(struct processor_pminfo *, processor_pminfo); DEFINE_PER_CPU_READ_MOSTLY(struct cpufreq_policy *, cpufreq_cpu_policy); DEFINE_PER_CPU(spinlock_t, cpufreq_statistic_lock); @@ -64,7 +64,7 @@ void cpufreq_statistic_update(unsigned i void cpufreq_statistic_update(unsigned int cpu, uint8_t from, uint8_t to) { struct pm_px *pxpt; - struct processor_pminfo *pmpt = processor_pminfo[cpu]; + struct processor_pminfo *pmpt = per_cpu(processor_pminfo, cpu); spinlock_t *cpufreq_statistic_lock = &per_cpu(cpufreq_statistic_lock, cpu); @@ -91,7 +91,7 @@ int cpufreq_statistic_init(unsigned int { uint32_t i, count; struct pm_px *pxpt; - const struct processor_pminfo *pmpt = processor_pminfo[cpuid]; + const struct processor_pminfo *pmpt = per_cpu(processor_pminfo, cpuid); spinlock_t *cpufreq_statistic_lock = &per_cpu(cpufreq_statistic_lock, cpuid); @@ -176,7 +176,7 @@ void cpufreq_statistic_reset(unsigned in { uint32_t i, j, count; struct pm_px *pxpt; - const struct processor_pminfo *pmpt = processor_pminfo[cpuid]; + const struct processor_pminfo *pmpt = per_cpu(processor_pminfo, cpuid); spinlock_t *cpufreq_statistic_lock = &per_cpu(cpufreq_statistic_lock, cpuid); diff -r 88fe9f780b3d -r eb601128d893 xen/include/acpi/cpufreq/cpufreq.h --- a/xen/include/acpi/cpufreq/cpufreq.h Thu May 26 17:16:47 2011 +0100 +++ b/xen/include/acpi/cpufreq/cpufreq.h Fri May 27 13:10:55 2011 +0200 @@ -29,8 +29,9 @@ struct acpi_cpufreq_data { struct acpi_cpufreq_data { struct processor_performance *acpi_data; struct cpufreq_frequency_table *freq_table; - unsigned int cpu_feature; + unsigned int arch_cpu_flags; }; +DECLARE_PER_CPU(struct acpi_cpufreq_data *, cpufreq_data); struct cpufreq_cpuinfo { unsigned int max_freq; diff -r 88fe9f780b3d -r eb601128d893 xen/include/acpi/cpufreq/processor_perf.h --- a/xen/include/acpi/cpufreq/processor_perf.h Thu May 26 17:16:47 2011 +0100 +++ b/xen/include/acpi/cpufreq/processor_perf.h Fri May 27 13:10:55 2011 +0200 @@ -41,7 +41,7 @@ struct processor_pminfo { struct processor_performance perf; }; -extern struct processor_pminfo *processor_pminfo[NR_CPUS]; +DECLARE_PER_CPU(struct processor_pminfo *, processor_pminfo); struct px_stat { uint8_t total; /* total Px states */