This is a note to let you know that I've just added the patch titled
cpufreq: Fix creation of symbolic links to policy directories
to the 4.9-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: cpufreq-fix-creation-of-symbolic-links-to-policy-directories.patch and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From foo@baz Thu Dec 21 09:02:40 CET 2017
From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com Date: Mon, 27 Mar 2017 19:33:09 +0200 Subject: cpufreq: Fix creation of symbolic links to policy directories
From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
[ Upstream commit 2f0ba790df51721794c11abc7a076d407392f648 ]
The cpufreq core only tries to create symbolic links from CPU directories in sysfs to policy directories in cpufreq_add_dev(), either when a given CPU is registered or when the cpufreq driver is registered, whichever happens first. That is not sufficient, however, because cpufreq_add_dev() may be called for an offline CPU whose policy object has not been created yet and, quite obviously, the symbolic cannot be added in that case.
Fix that by making cpufreq_online() attempt to add symbolic links to policy objects for the CPUs in the related_cpus mask of every new policy object created by it.
The cpufreq_driver_lock locking around the for_each_cpu() loop in cpufreq_online() is dropped, because it is not necessary and the code is somewhat simpler without it. Moreover, failures to create a symbolic link will not be regarded as hard errors any more and the CPUs without those links will not be taken offline automatically, but that should not be problematic in practice.
Reported-and-tested-by: Prashanth Prakash pprakash@codeaurora.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Cc: 4.9+ stable@vger.kernel.org # 4.9+ Signed-off-by: Sasha Levin alexander.levin@verizon.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/cpufreq/cpufreq.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-)
--- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -918,11 +918,19 @@ static struct kobj_type ktype_cpufreq = .release = cpufreq_sysfs_release, };
-static int add_cpu_dev_symlink(struct cpufreq_policy *policy, - struct device *dev) +static void add_cpu_dev_symlink(struct cpufreq_policy *policy, unsigned int cpu) { + struct device *dev = get_cpu_device(cpu); + + if (!dev) + return; + + if (cpumask_test_and_set_cpu(cpu, policy->real_cpus)) + return; + dev_dbg(dev, "%s: Adding symlink\n", __func__); - return sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq"); + if (sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq")) + dev_err(dev, "cpufreq symlink creation failed\n"); }
static void remove_cpu_dev_symlink(struct cpufreq_policy *policy, @@ -1184,10 +1192,10 @@ static int cpufreq_online(unsigned int c policy->user_policy.min = policy->min; policy->user_policy.max = policy->max;
- write_lock_irqsave(&cpufreq_driver_lock, flags); - for_each_cpu(j, policy->related_cpus) + for_each_cpu(j, policy->related_cpus) { per_cpu(cpufreq_cpu_data, j) = policy; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); + add_cpu_dev_symlink(policy, j); + } } else { policy->min = policy->user_policy.min; policy->max = policy->user_policy.max; @@ -1284,13 +1292,15 @@ out_exit_policy:
if (cpufreq_driver->exit) cpufreq_driver->exit(policy); + + for_each_cpu(j, policy->real_cpus) + remove_cpu_dev_symlink(policy, get_cpu_device(j)); + out_free_policy: cpufreq_policy_free(policy, !new_policy); return ret; }
-static int cpufreq_offline(unsigned int cpu); - /** * cpufreq_add_dev - the cpufreq interface for a CPU device. * @dev: CPU device. @@ -1312,16 +1322,10 @@ static int cpufreq_add_dev(struct device
/* Create sysfs link on CPU registration */ policy = per_cpu(cpufreq_cpu_data, cpu); - if (!policy || cpumask_test_and_set_cpu(cpu, policy->real_cpus)) - return 0; + if (policy) + add_cpu_dev_symlink(policy, cpu);
- ret = add_cpu_dev_symlink(policy, dev); - if (ret) { - cpumask_clear_cpu(cpu, policy->real_cpus); - cpufreq_offline(cpu); - } - - return ret; + return 0; }
static int cpufreq_offline(unsigned int cpu)
Patches currently in stable-queue which might be from rafael.j.wysocki@intel.com are
queue-4.9/cpuidle-validate-cpu_dev-in-cpuidle_add_sysfs.patch queue-4.9/cpuidle-fix-broadcast-control-when-broadcast-can-not-be-entered.patch queue-4.9/cpuidle-powernv-pass-correct-drv-cpumask-for-registration.patch queue-4.9/pm-opp-move-error-message-to-debug-level.patch queue-4.9/cpufreq-fix-creation-of-symbolic-links-to-policy-directories.patch