cpufreq: Clear policy->cpus bits in __cpufreq_remove_dev_finish()
This broke after a recent change "cedb70a cpufreq: Split __cpufreq_remove_dev() into two parts" from Srivatsa. Consider a scenario where we have two CPUs in a policy (0 & 1) and we are removing CPU 1. On the call to __cpufreq_remove_dev_prepare() we have cleared 1 from policy->cpus and now on a call to __cpufreq_remove_dev_finish() we read cpumask_weight of policy->cpus, which will come as 1 and this code will behave as if we are removing the last CPU from policy :) Fix it by clearing the CPU mask in __cpufreq_remove_dev_finish() instead of __cpufreq_remove_dev_prepare(). Tested-by: Stephen Warren <swarren@wwwdotorg.org> Reviewed-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
272b98c645
commit
9c8f1ee40b
1 changed files with 8 additions and 8 deletions
|
@ -1125,7 +1125,7 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* first sibling now owns the new sysfs dir */
|
/* first sibling now owns the new sysfs dir */
|
||||||
cpu_dev = get_cpu_device(cpumask_first(policy->cpus));
|
cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu));
|
||||||
|
|
||||||
/* Don't touch sysfs files during light-weight tear-down */
|
/* Don't touch sysfs files during light-weight tear-down */
|
||||||
if (frozen)
|
if (frozen)
|
||||||
|
@ -1189,12 +1189,9 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
|
||||||
policy->governor->name, CPUFREQ_NAME_LEN);
|
policy->governor->name, CPUFREQ_NAME_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WARN_ON(lock_policy_rwsem_write(cpu));
|
lock_policy_rwsem_read(cpu);
|
||||||
cpus = cpumask_weight(policy->cpus);
|
cpus = cpumask_weight(policy->cpus);
|
||||||
|
unlock_policy_rwsem_read(cpu);
|
||||||
if (cpus > 1)
|
|
||||||
cpumask_clear_cpu(cpu, policy->cpus);
|
|
||||||
unlock_policy_rwsem_write(cpu);
|
|
||||||
|
|
||||||
if (cpu != policy->cpu) {
|
if (cpu != policy->cpu) {
|
||||||
if (!frozen)
|
if (!frozen)
|
||||||
|
@ -1237,9 +1234,12 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_policy_rwsem_read(cpu);
|
WARN_ON(lock_policy_rwsem_write(cpu));
|
||||||
cpus = cpumask_weight(policy->cpus);
|
cpus = cpumask_weight(policy->cpus);
|
||||||
unlock_policy_rwsem_read(cpu);
|
|
||||||
|
if (cpus > 1)
|
||||||
|
cpumask_clear_cpu(cpu, policy->cpus);
|
||||||
|
unlock_policy_rwsem_write(cpu);
|
||||||
|
|
||||||
/* If cpu is last user of policy, free policy */
|
/* If cpu is last user of policy, free policy */
|
||||||
if (cpus == 1) {
|
if (cpus == 1) {
|
||||||
|
|
Loading…
Reference in a new issue