cpufreq: sched: Fix kernel crash on accessing sysfs file
authorViresh Kumar <viresh.kumar@linaro.org>
Tue, 15 Nov 2016 06:28:52 +0000 (11:58 +0530)
committerDmitry Shmidt <dimitrysh@google.com>
Wed, 16 Nov 2016 17:46:21 +0000 (09:46 -0800)
If the cpufreq driver hasn't set the CPUFREQ_HAVE_GOVERNOR_PER_POLICY
flag, then the kernel will crash on accessing sysfs files for the sched
governor.

CPUFreq governors we can have the governor specific sysfs files in two
places:

A. /sys/devices/system/cpu/cpuX/cpufreq/<governor>
B. /sys/devices/system/cpu/cpufreq/<governor>

The case A. is for governor per policy case, where we can control the
governor tunables for each policy separately. The case B. is for system
wide tunable values.

The schedfreq governor only implements the case A. and not B.  The sysfs
files in case B will still be present in
/sys/devices/system/cpu/cpufreq/<governor>, but accessing them will
crash kernel as the governor doesn't support that.

Moreover the sched governor is pretty new and will be used only for the
ARM platforms and there is no need to support the case B at all.

Hence use policy->kobj instead of get_governor_parent_kobj(), so that we
always create the sysfs files in path A.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
kernel/sched/cpufreq_sched.c

index f6f9b9b3a4a8367a2753c82b27a373a73b3f3ddd..d751bc2d0d6e50f0549551088913c8f5dcdb77ad 100644 (file)
@@ -289,7 +289,7 @@ static int cpufreq_sched_policy_init(struct cpufreq_policy *policy)
        pr_debug("%s: throttle threshold = %u [ns]\n",
                  __func__, gd->up_throttle_nsec);
 
-       rc = sysfs_create_group(get_governor_parent_kobj(policy), get_sysfs_attr());
+       rc = sysfs_create_group(&policy->kobj, get_sysfs_attr());
        if (rc) {
                pr_err("%s: couldn't create sysfs attributes: %d\n", __func__, rc);
                goto err;
@@ -332,7 +332,7 @@ static int cpufreq_sched_policy_exit(struct cpufreq_policy *policy)
                put_task_struct(gd->task);
        }
 
-       sysfs_remove_group(get_governor_parent_kobj(policy), get_sysfs_attr());
+       sysfs_remove_group(&policy->kobj, get_sysfs_attr());
 
        policy->governor_data = NULL;