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 <jbeulich@suse.com>
---
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);
On 2026-01-22 04:42, Jan Beulich wrote: > 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 <jbeulich@suse.com> Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
© 2016 - 2026 Red Hat, Inc.