Skip to content

Commit c4d61a5

Browse files
vireshkrafaeljw
authored andcommitted
cpufreq: Don't unregister cpufreq cooling on CPU hotplug
Offlining a CPU and bringing it back online is a common operation and it happens frequently during system suspend/resume, where the non-boot CPUs are hotplugged out during suspend and brought back at resume. The cpufreq core already tries to make this path as fast as possible as the changes are only temporary in nature and full cleanup of resources isn't required in this case. For example the drivers can implement online()/offline() callbacks to avoid a lot of tear down of resources. On similar lines, there is no need to unregister the cpufreq cooling device during suspend / resume, but only while the policy is getting removed. Moreover, unregistering the cpufreq cooling device is resulting in an unwanted outcome, where the system suspend is eventually aborted in the process. Currently, during system suspend the cpufreq core unregisters the cooling device, which in turn removes a kobject using device_del() and that generates a notification to the userspace via uevent broadcast. This causes system suspend to abort in some setups. This was also earlier reported (indirectly) by Roman [1]. Maybe there is another way around to fixing that problem properly, but this change makes sense anyways. Move the registering and unregistering of the cooling device to policy creation and removal times onlyy. Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218521 Reported-by: Manaf Meethalavalappu Pallikunhi <[email protected]> Reported-by: Roman Stratiienko <[email protected]> Link: https://patchwork.kernel.org/project/linux-pm/patch/[email protected]/ [1] Tested-by: Manaf Meethalavalappu Pallikunhi <[email protected]> Signed-off-by: Viresh Kumar <[email protected]> Reviewed-by: Dhruva Gole <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent a755d0e commit c4d61a5

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

drivers/cpufreq/cpufreq.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,8 @@ static int cpufreq_online(unsigned int cpu)
15801580
if (cpufreq_driver->ready)
15811581
cpufreq_driver->ready(policy);
15821582

1583-
if (cpufreq_thermal_control_enabled(cpufreq_driver))
1583+
/* Register cpufreq cooling only for a new policy */
1584+
if (new_policy && cpufreq_thermal_control_enabled(cpufreq_driver))
15841585
policy->cdev = of_cpufreq_cooling_register(policy);
15851586

15861587
pr_debug("initialization complete\n");
@@ -1664,11 +1665,6 @@ static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy)
16641665
else
16651666
policy->last_policy = policy->policy;
16661667

1667-
if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
1668-
cpufreq_cooling_unregister(policy->cdev);
1669-
policy->cdev = NULL;
1670-
}
1671-
16721668
if (has_target())
16731669
cpufreq_exit_governor(policy);
16741670

@@ -1729,6 +1725,15 @@ static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
17291725
return;
17301726
}
17311727

1728+
/*
1729+
* Unregister cpufreq cooling once all the CPUs of the policy are
1730+
* removed.
1731+
*/
1732+
if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
1733+
cpufreq_cooling_unregister(policy->cdev);
1734+
policy->cdev = NULL;
1735+
}
1736+
17321737
/* We did light-weight exit earlier, do full tear down now */
17331738
if (cpufreq_driver->offline)
17341739
cpufreq_driver->exit(policy);

0 commit comments

Comments
 (0)