Commit 89af7ba5 authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Greg Kroah-Hartman

cpu-hotplug: convert cpu_hotplug_disabled to a counter

As a prerequisite to exporting cpu_hotplug_enable/cpu_hotplug_disable
functions to modules we need to convert cpu_hotplug_disabled to a counter
to properly support disable -> disable -> enable call sequences. E.g.
after Hyper-V vmbus module (which is supposed to be the first user of
exported cpu_hotplug_enable/cpu_hotplug_disable) did cpu_hotplug_disable()
hibernate path calls disable_nonboot_cpus() and if we hit an error in
_cpu_down() enable_nonboot_cpus() will be called on the failure path (thus
making cpu_hotplug_disabled = 0 and leaving cpu hotplug in 'enabled'
state). Same problem is possible if more than 1 module use
cpu_hotplug_disable/cpu_hotplug_enable on their load/unload paths. When
one of these modules is been unloaded it is logical to leave cpu hotplug
in 'disabled' state.

To support the change we need to increse cpu_hotplug_disabled counter
in disable_nonboot_cpus() unconditionally as all users of
disable_nonboot_cpus() are supposed to do enable_nonboot_cpus() in case
an error was returned.
Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 54bf725e
...@@ -72,7 +72,7 @@ More details follow: ...@@ -72,7 +72,7 @@ More details follow:
| |
v v
Disable regular cpu hotplug Disable regular cpu hotplug
by setting cpu_hotplug_disabled=1 by increasing cpu_hotplug_disabled
| |
v v
Release cpu_add_remove_lock Release cpu_add_remove_lock
...@@ -89,7 +89,7 @@ Resuming back is likewise, with the counterparts being (in the order of ...@@ -89,7 +89,7 @@ Resuming back is likewise, with the counterparts being (in the order of
execution during resume): execution during resume):
* enable_nonboot_cpus() which involves: * enable_nonboot_cpus() which involves:
| Acquire cpu_add_remove_lock | Acquire cpu_add_remove_lock
| Reset cpu_hotplug_disabled to 0, thereby enabling regular cpu hotplug | Decrease cpu_hotplug_disabled, thereby enabling regular cpu hotplug
| Call _cpu_up() [for all those cpus in the frozen_cpus mask, in a loop] | Call _cpu_up() [for all those cpus in the frozen_cpus mask, in a loop]
| Release cpu_add_remove_lock | Release cpu_add_remove_lock
v v
...@@ -120,7 +120,7 @@ after the entire cycle is complete (i.e., suspend + resume). ...@@ -120,7 +120,7 @@ after the entire cycle is complete (i.e., suspend + resume).
Acquire cpu_add_remove_lock Acquire cpu_add_remove_lock
| |
v v
If cpu_hotplug_disabled is 1 If cpu_hotplug_disabled > 0
return gracefully return gracefully
| |
| |
......
...@@ -191,14 +191,14 @@ void cpu_hotplug_done(void) ...@@ -191,14 +191,14 @@ void cpu_hotplug_done(void)
void cpu_hotplug_disable(void) void cpu_hotplug_disable(void)
{ {
cpu_maps_update_begin(); cpu_maps_update_begin();
cpu_hotplug_disabled = 1; cpu_hotplug_disabled++;
cpu_maps_update_done(); cpu_maps_update_done();
} }
void cpu_hotplug_enable(void) void cpu_hotplug_enable(void)
{ {
cpu_maps_update_begin(); cpu_maps_update_begin();
cpu_hotplug_disabled = 0; WARN_ON(--cpu_hotplug_disabled < 0);
cpu_maps_update_done(); cpu_maps_update_done();
} }
...@@ -608,13 +608,18 @@ int disable_nonboot_cpus(void) ...@@ -608,13 +608,18 @@ int disable_nonboot_cpus(void)
} }
} }
if (!error) { if (!error)
BUG_ON(num_online_cpus() > 1); BUG_ON(num_online_cpus() > 1);
/* Make sure the CPUs won't be enabled by someone else */ else
cpu_hotplug_disabled = 1;
} else {
pr_err("Non-boot CPUs are not disabled\n"); pr_err("Non-boot CPUs are not disabled\n");
}
/*
* Make sure the CPUs won't be enabled by someone else. We need to do
* this even in case of failure as all disable_nonboot_cpus() users are
* supposed to do enable_nonboot_cpus() on the failure path.
*/
cpu_hotplug_disabled++;
cpu_maps_update_done(); cpu_maps_update_done();
return error; return error;
} }
...@@ -633,7 +638,7 @@ void __ref enable_nonboot_cpus(void) ...@@ -633,7 +638,7 @@ void __ref enable_nonboot_cpus(void)
/* Allow everyone to use the CPU hotplug again */ /* Allow everyone to use the CPU hotplug again */
cpu_maps_update_begin(); cpu_maps_update_begin();
cpu_hotplug_disabled = 0; WARN_ON(--cpu_hotplug_disabled < 0);
if (cpumask_empty(frozen_cpus)) if (cpumask_empty(frozen_cpus))
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment