Skip to content

Commit f339f35

Browse files
committed
cpufreq: Rearrange locking in cpufreq_remove_dev()
Currently, cpufreq_remove_dev() invokes the ->exit() driver callback without holding the policy rwsem which is inconsistent with what happens if ->exit() is invoked directly from cpufreq_offline(). It also manipulates the real_cpus mask and removes the CPU device symlink without holding the policy rwsem, but cpufreq_offline() holds the rwsem around the modifications thereof. For consistency, modify cpufreq_remove_dev() to hold the policy rwsem until the ->exit() callback has been called (or it has been determined that it is not necessary to call it). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
1 parent fddd8f8 commit f339f35

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

drivers/cpufreq/cpufreq.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,18 +1660,25 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
16601660
if (!policy)
16611661
return;
16621662

1663+
down_write(&policy->rwsem);
1664+
16631665
if (cpu_online(cpu))
1664-
cpufreq_offline(cpu);
1666+
__cpufreq_offline(cpu, policy);
16651667

16661668
remove_cpu_dev_symlink(policy, cpu, dev);
16671669

1668-
if (cpumask_empty(policy->real_cpus)) {
1669-
/* We did light-weight exit earlier, do full tear down now */
1670-
if (cpufreq_driver->offline)
1671-
cpufreq_driver->exit(policy);
1672-
1673-
cpufreq_policy_free(policy);
1670+
if (!cpumask_empty(policy->real_cpus)) {
1671+
up_write(&policy->rwsem);
1672+
return;
16741673
}
1674+
1675+
/* We did light-weight exit earlier, do full tear down now */
1676+
if (cpufreq_driver->offline)
1677+
cpufreq_driver->exit(policy);
1678+
1679+
up_write(&policy->rwsem);
1680+
1681+
cpufreq_policy_free(policy);
16751682
}
16761683

16771684
/**

0 commit comments

Comments
 (0)