Possibly many slots of it may be unused (all of them when the HWP or CPPC drivers are in use), as it's always strictly associated with the CPU recorded in a policy (irrespective of that CPU intermediately being taken offline). It is shared by all CPUs sharing a policy. We could therefore put the respective pointers in struct cpufreq_policy, but even that level of indirection is pointless. Embed the driver data structure directly in the policy one.
Signed-off-by: Jan Beulich <[email protected]> --- v2: Re-base, use union. --- a/xen/arch/x86/acpi/cpufreq/acpi.c +++ b/xen/arch/x86/acpi/cpufreq/acpi.c @@ -174,17 +174,18 @@ static u32 get_cur_val(const cpumask_t * return 0; policy = per_cpu(cpufreq_cpu_policy, cpu); - if (!policy || !cpufreq_drv_data[policy->cpu]) + if ( !policy ) return 0; - switch (cpufreq_drv_data[policy->cpu]->arch_cpu_flags) { + switch ( policy->drv_data.acpi.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 = cpufreq_drv_data[policy->cpu]->acpi_data; + perf = policy->drv_data.acpi.acpi_data; cmd.addr.io.port = perf->control_register.address; cmd.addr.io.bit_width = perf->control_register.bit_width; break; @@ -210,9 +211,8 @@ static unsigned int cf_check get_cur_fre if (!policy) return 0; - data = cpufreq_drv_data[policy->cpu]; - if (unlikely(data == NULL || - data->acpi_data == NULL || data->freq_table == NULL)) + data = &policy->drv_data.acpi; + if ( !data->acpi_data || !data->freq_table ) return 0; return extract_freq(get_cur_val(cpumask_of(cpu)), data); @@ -252,7 +252,7 @@ static int cf_check acpi_cpufreq_target( struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - struct acpi_cpufreq_data *data = cpufreq_drv_data[policy->cpu]; + struct acpi_cpufreq_data *data = &policy->drv_data.acpi; struct processor_performance *perf; struct cpufreq_freqs freqs; cpumask_t online_policy_cpus; @@ -262,10 +262,8 @@ static int cf_check acpi_cpufreq_target( unsigned int j; int result = 0; - if (unlikely(data == NULL || - data->acpi_data == NULL || data->freq_table == NULL)) { + if ( !data->acpi_data || !data->freq_table ) return -ENODEV; - } if (policy->turbo == CPUFREQ_TURBO_DISABLED) if (target_freq > policy->cpuinfo.second_max_freq) @@ -331,11 +329,9 @@ static int cf_check acpi_cpufreq_target( static int cf_check acpi_cpufreq_verify(struct cpufreq_policy *policy) { - struct acpi_cpufreq_data *data; struct processor_performance *perf; - if (!policy || !(data = cpufreq_drv_data[policy->cpu]) || - !processor_pminfo[policy->cpu]) + if ( !policy || !processor_pminfo[policy->cpu] ) return -EINVAL; perf = &processor_pminfo[policy->cpu]->perf; @@ -343,7 +339,8 @@ static int cf_check acpi_cpufreq_verify( cpufreq_verify_within_limits(policy, 0, perf->states[perf->platform_limit].core_frequency * 1000); - return cpufreq_frequency_table_verify(policy, data->freq_table); + return cpufreq_frequency_table_verify(policy, + policy->drv_data.acpi.freq_table); } static unsigned long @@ -379,17 +376,11 @@ static int cf_check acpi_cpufreq_cpu_ini unsigned int i; unsigned int valid_states = 0; unsigned int cpu = policy->cpu; - struct acpi_cpufreq_data *data; + struct acpi_cpufreq_data *data = &policy->drv_data.acpi; unsigned int result = 0; struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; struct processor_performance *perf; - data = xzalloc(struct acpi_cpufreq_data); - if (!data) - return -ENOMEM; - - cpufreq_drv_data[cpu] = data; - data->acpi_data = &processor_pminfo[cpu]->perf; perf = data->acpi_data; @@ -406,23 +397,18 @@ static int cf_check acpi_cpufreq_cpu_ini if (cpufreq_verbose) printk("xen_pminfo: @acpi_cpufreq_cpu_init," "HARDWARE addr space\n"); - if (!cpu_has(c, X86_FEATURE_EIST)) { - result = -ENODEV; - goto err_unreg; - } + if ( !cpu_has(c, X86_FEATURE_EIST) ) + return -ENODEV; data->arch_cpu_flags = SYSTEM_INTEL_MSR_CAPABLE; break; default: - result = -ENODEV; - goto err_unreg; + return -ENODEV; } data->freq_table = xmalloc_array(struct cpufreq_frequency_table, (perf->state_count+1)); - if (!data->freq_table) { - result = -ENOMEM; - goto err_unreg; - } + if ( !data->freq_table ) + return -ENOMEM; /* detect transition latency */ policy->cpuinfo.transition_latency = 0; @@ -480,23 +466,14 @@ static int cf_check acpi_cpufreq_cpu_ini return result; err_freqfree: - xfree(data->freq_table); -err_unreg: - xfree(data); - cpufreq_drv_data[cpu] = NULL; + XFREE(data->freq_table); return result; } static int cf_check acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) { - struct acpi_cpufreq_data *data = cpufreq_drv_data[policy->cpu]; - - if (data) { - cpufreq_drv_data[policy->cpu] = NULL; - xfree(data->freq_table); - xfree(data); - } + XFREE(policy->drv_data.acpi.freq_table); return 0; } --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c @@ -35,8 +35,6 @@ #include <acpi/cpufreq/cpufreq.h> -struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS]; - struct perf_pair { union { struct { --- a/xen/arch/x86/acpi/cpufreq/powernow.c +++ b/xen/arch/x86/acpi/cpufreq/powernow.c @@ -84,16 +84,14 @@ static int cf_check powernow_cpufreq_tar struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - struct acpi_cpufreq_data *data = cpufreq_drv_data[policy->cpu]; + struct acpi_cpufreq_data *data = &policy->drv_data.acpi; struct processor_performance *perf; unsigned int next_state; /* Index into freq_table */ unsigned int next_perf_state; /* Index into perf table */ int result; - if (unlikely(data == NULL || - data->acpi_data == NULL || data->freq_table == NULL)) { + if ( !data->acpi_data || !data->freq_table ) return -ENODEV; - } perf = data->acpi_data; result = cpufreq_frequency_table_target(policy, @@ -187,11 +185,9 @@ static void cf_check get_cpu_data(void * static int cf_check powernow_cpufreq_verify(struct cpufreq_policy *policy) { - struct acpi_cpufreq_data *data; struct processor_performance *perf; - if (!policy || !(data = cpufreq_drv_data[policy->cpu]) || - !processor_pminfo[policy->cpu]) + if ( !policy || !processor_pminfo[policy->cpu] ) return -EINVAL; perf = &processor_pminfo[policy->cpu]->perf; @@ -199,7 +195,8 @@ static int cf_check powernow_cpufreq_ver cpufreq_verify_within_limits(policy, 0, perf->states[perf->platform_limit].core_frequency * 1000); - return cpufreq_frequency_table_verify(policy, data->freq_table); + return cpufreq_frequency_table_verify(policy, + policy->drv_data.acpi.freq_table); } static int cf_check powernow_cpufreq_cpu_init(struct cpufreq_policy *policy) @@ -207,18 +204,12 @@ static int cf_check powernow_cpufreq_cpu unsigned int i; unsigned int valid_states = 0; unsigned int cpu = policy->cpu; - struct acpi_cpufreq_data *data; + struct acpi_cpufreq_data *data = &policy->drv_data.acpi; unsigned int result = 0; struct processor_performance *perf; struct amd_cpu_data info; struct cpuinfo_x86 *c = &cpu_data[policy->cpu]; - data = xzalloc(struct acpi_cpufreq_data); - if (!data) - return -ENOMEM; - - cpufreq_drv_data[cpu] = data; - data->acpi_data = &processor_pminfo[cpu]->perf; info.perf = perf = data->acpi_data; @@ -230,8 +221,7 @@ static int cf_check powernow_cpufreq_cpu if (cpumask_weight(policy->cpus) != 1) { printk(XENLOG_WARNING "Unsupported sharing type %d (%u CPUs)\n", policy->shared_type, cpumask_weight(policy->cpus)); - result = -ENODEV; - goto err_unreg; + return -ENODEV; } } else { cpumask_copy(policy->cpus, cpumask_of(cpu)); @@ -240,21 +230,16 @@ static int cf_check powernow_cpufreq_cpu /* capability check */ if (perf->state_count <= 1) { printk("No P-States\n"); - result = -ENODEV; - goto err_unreg; + return -ENODEV; } - if (perf->control_register.space_id != perf->status_register.space_id) { - result = -ENODEV; - goto err_unreg; - } + if ( perf->control_register.space_id != perf->status_register.space_id ) + return -ENODEV; data->freq_table = xmalloc_array(struct cpufreq_frequency_table, (perf->state_count+1)); - if (!data->freq_table) { - result = -ENOMEM; - goto err_unreg; - } + if ( !data->freq_table ) + return -ENOMEM; /* detect transition latency */ policy->cpuinfo.transition_latency = 0; @@ -300,23 +285,14 @@ static int cf_check powernow_cpufreq_cpu return result; err_freqfree: - xfree(data->freq_table); -err_unreg: - xfree(data); - cpufreq_drv_data[cpu] = NULL; + XFREE(data->freq_table); return result; } static int cf_check powernow_cpufreq_cpu_exit(struct cpufreq_policy *policy) { - struct acpi_cpufreq_data *data = cpufreq_drv_data[policy->cpu]; - - if (data) { - cpufreq_drv_data[policy->cpu] = NULL; - xfree(data->freq_table); - xfree(data); - } + XFREE(policy->drv_data.acpi.freq_table); return 0; } --- a/xen/include/acpi/cpufreq/cpufreq.h +++ b/xen/include/acpi/cpufreq/cpufreq.h @@ -38,8 +38,6 @@ struct acpi_cpufreq_data { unsigned int arch_cpu_flags; }; -extern struct acpi_cpufreq_data *cpufreq_drv_data[NR_CPUS]; - struct cpufreq_cpuinfo { unsigned int max_freq; unsigned int second_max_freq; /* P1 if Turbo Mode is on */ @@ -82,6 +80,10 @@ struct cpufreq_policy { * -1 for disable, 1 for enabled * See CPUFREQ_TURBO_* below for defines */ unsigned int policy; /* CPUFREQ_POLICY_* */ + + union { + struct acpi_cpufreq_data acpi; + } drv_data; }; DECLARE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_policy);
