acpi-cpufreq: use same acpi_cpufreq_data if policy is shared
PATCH 1/1 acpi-cpufreq: use same acpi_cpufreq_data if policy is shared
cpufreq core will mark all cpus in policy->cpus as initialized by setting percpu cpufreq_cpu_data = policy.
However in acpi-cpufreq, we did not set percpu acpi_cpufreq_data for all cpus in policy->cpus.
That will cause a issue that when we call get_cur_freq_on_cpu for a cpu, it returns zero instead of a correct value.
So we shared acpi_cpufreq_data for all those cpus in policy->cpus.
--- drivers/cpufreq/acpi-cpufreq.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/cpufreq/acpi-cpufreq.c +12 -2
@@ -673,6 +673,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) } data->acpi_data =per_cpu_ptr (acpi_perf_data, cpu); +cpumask_copy (policy->cpus,cpumask_of (cpu));per_cpu (acfreq_data, cpu) = data;if (cpu_has (c,X86_FEATURE_CONSTANT_TSC ))
@@ -712,6 +713,10 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) }#endif +for_each_cpu (i, policy->cpus) { +per_cpu (acfreq_data, i) = data; + } +/* capability check */ if (perf->state_count <=1 ) {pr_debug ("No P-States\n" );
@@ -843,7 +848,9 @@ err_free_mask:free_cpumask_var (data->freqdomain_cpus); err_free:kfree (data); -per_cpu (acfreq_data, cpu) =NULL ; +for_each_cpu (i, policy->cpus) { +per_cpu (acfreq_data, i) =NULL ; + }return result; }
@@ -851,11 +858,14 @@ err_free:static int acpi_cpufreq_cpu_exit (struct cpufreq_policy *policy) {struct acpi_cpufreq_data *data =per_cpu (acfreq_data, policy->cpu); +int i;pr_debug ("acpi_cpufreq_cpu_exit\n" );if (data) { -per_cpu (acfreq_data, policy->cpu) =NULL ; +for_each_cpu (i, policy->cpus) { +per_cpu (acfreq_data, i) =NULL ; + }acpi_processor_unregister_performance (data->acpi_data, policy->cpu);free_cpumask_var (data->freqdomain_cpus);
Signature · 1 line
1.9.1
Viresh Kumar
maintainerQuoted 20 lines · Pan Xinhui
cpufreq core will mark all cpus in
policy->cpusas initialized by setting percpucpufreq_cpu_data= policy.
However in acpi-cpufreq, we did not set percpuacpi_cpufreq_datafor all cpus inpolicy->cpus.
That will cause a issue that when we callget_cur_freq_on_cpufor a cpu, it returns zero instead of a correct value.So we shared
acpi_cpufreq_datafor all those cpus inpolicy->cpus.Signed-off-by xinhuix.pan <[email protected]>--- drivers/cpufreq/acpi-cpufreq.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)drivers/cpufreq/acpi-cpufreq.c +0
-0
drivers/cpufreq/acpi-cpufreq.c static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) · line 676
Quoted 4 lines
drivers/cpufreq/acpi-cpufreq.c +1
-0@@ -673,6 +673,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) } data->acpi_data =per_cpu_ptr (acpi_perf_data, cpu); +cpumask_copy (policy->cpus,cpumask_of (cpu));
This is already done by cpufreq-core before calling ->init() and so isn't required.
Quoted 15 lines
drivers/cpufreq/acpi-cpufreq.c +4
-0per_cpu (acfreq_data, cpu) = data;if (cpu_has (c,X86_FEATURE_CONSTANT_TSC ))@@ -712,6 +713,10 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) }#endif +for_each_cpu (i, policy->cpus) { +per_cpu (acfreq_data, i) = data; + } +/* capability check */ if (perf->state_count <=1 ) {pr_debug ("No P-States\n" );
drivers/cpufreq/acpi-cpufreq.c err_free_mask: · line 853
Quoted 7 lines
drivers/cpufreq/acpi-cpufreq.c +3
-1@@ -843,7 +848,9 @@ err_free_mask:free_cpumask_var (data->freqdomain_cpus); err_free:kfree (data); -per_cpu (acfreq_data, cpu) =NULL ; +for_each_cpu (i, policy->cpus) { +per_cpu (acfreq_data, i) =NULL ; + }
The per-cpu thing is basically wrong to start with. cpufreq-policy has a field: 'driver_data', which can be used to replace this acfreq_data. Probably use that and things will get fixed by themselves.
Signature · 1 line
viresh