acpi-cpufreq: Fix an ACPI perf unregister issue
authorPan Xinhui <xinhuix.pan@intel.com>
Fri, 10 Jul 2015 06:36:20 +0000 (14:36 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 16 Jul 2015 21:51:26 +0000 (23:51 +0200)
As policy->cpu may not be same in acpi_cpufreq_cpu_init() and
acpi_cpufreq_cpu_exit(). There is a risk that we use different CPU
to un/register ACPI performance. So acpi_processor_unregister_performance()
may not be able to do the cleanup work. That causes a memory leak. And
if there will be another acpi_processor_register_performance() call,
it may also fail thanks to the internal check of pr->performace.

So add a new struct acpi_cpufreq_data field, acpi_perf_cpu, to fix
this issue.

Signed-off-by: Pan Xinhui <xinhuix.pan@intel.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
[ rjw: Changelog ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/acpi-cpufreq.c

index e7fcaa6..de54ce1 100644 (file)
@@ -69,6 +69,7 @@ struct acpi_cpufreq_data {
        struct cpufreq_frequency_table *freq_table;
        unsigned int resume;
        unsigned int cpu_feature;
+       unsigned int acpi_perf_cpu;
        cpumask_var_t freqdomain_cpus;
 };
 
@@ -677,6 +678,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        }
 
        data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
+       data->acpi_perf_cpu = cpu;
        policy->driver_data = data;
 
        if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
@@ -861,7 +863,7 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
        if (data) {
                policy->driver_data = NULL;
                acpi_processor_unregister_performance(data->acpi_data,
-                                                     policy->cpu);
+                                                     data->acpi_perf_cpu);
                free_cpumask_var(data->freqdomain_cpus);
                kfree(data->freq_table);
                kfree(data);