cpufreq: stats: do cpufreq_cpu_put() corresponding to cpufreq_cpu_get()
authorviresh kumar <viresh.kumar@linaro.org>
Fri, 22 Mar 2013 10:13:52 +0000 (10:13 +0000)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 25 Mar 2013 14:13:16 +0000 (15:13 +0100)
In cpufreq_stats_free_sysfs() we aren't balancing calls to
cpufreq_cpu_get() with cpufreq_cpu_put(). This will never let us have
ref count to policy->kobj as zero.

We will get a hang if somehow cpufreq_driver_unregister() is called.
And that can happen when we compile our driver as module and
insmod/rmmod it.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Acked-by: Amit Kucheria <amit.kucheria@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/cpufreq/cpufreq_stats.c

index 2fd779eb1ed1f9fcdb7cb70ab54ed319fe1e4160..bfd6273fd873531d864f3b4e104d37018a5d8dda 100644 (file)
@@ -180,15 +180,19 @@ static void cpufreq_stats_free_sysfs(unsigned int cpu)
 {
        struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
 
-       if (!cpufreq_frequency_get_table(cpu))
+       if (!policy)
                return;
 
-       if (policy && !policy_is_shared(policy)) {
+       if (!cpufreq_frequency_get_table(cpu))
+               goto put_ref;
+
+       if (!policy_is_shared(policy)) {
                pr_debug("%s: Free sysfs stat\n", __func__);
                sysfs_remove_group(&policy->kobj, &stats_attr_group);
        }
-       if (policy)
-               cpufreq_cpu_put(policy);
+
+put_ref:
+       cpufreq_cpu_put(policy);
 }
 
 static int cpufreq_stats_create_table(struct cpufreq_policy *policy,