cpufreq: interactive: hold reference on global cpufreq kobject if needed
authorGreg Hackmann <ghackmann@google.com>
Mon, 8 Dec 2014 18:08:35 +0000 (10:08 -0800)
committerJohn Stultz <john.stultz@linaro.org>
Tue, 16 Feb 2016 21:53:01 +0000 (13:53 -0800)
2361be23666232dbb4851a527f466c4cbf5340fc changed cpufreq to add the
global cpufreq kobject to sysfs on demand.

To ensure this happens, cpufreq_interactive must hold a reference on
this object on devices where it intends to use it (i.e., devices where
have_governor_per_policy() returns false).  Otherwise a parentless
kobject will be passed to sysfs_create_group() which will subsequently
BUG().

Change-Id: I7dd03956e1d3c6c3c0cc17c799882c235804ae09
Signed-off-by: Greg Hackmann <ghackmann@google.com>
drivers/cpufreq/cpufreq_interactive.c

index ff77b300df88b3a504753527603043b35a49d385..786fd012e8b222dec030223643f3ae52b4993aeb 100644 (file)
@@ -1154,8 +1154,10 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
                spin_lock_init(&tunables->above_hispeed_delay_lock);
 
                policy->governor_data = tunables;
-               if (!have_governor_per_policy())
+               if (!have_governor_per_policy()) {
                        common_tunables = tunables;
+                       WARN_ON(cpufreq_get_global_kobject());
+               }
 
                rc = sysfs_create_group(get_governor_parent_kobj(policy),
                                get_sysfs_attr());
@@ -1185,6 +1187,10 @@ static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
 
                        sysfs_remove_group(get_governor_parent_kobj(policy),
                                        get_sysfs_attr());
+
+                       if (!have_governor_per_policy())
+                               cpufreq_put_global_kobject();
+
                        kfree(tunables);
                        common_tunables = NULL;
                }