aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Cochran <[email protected]>2016-07-27 11:08:18 +0200
committerIngo Molnar <[email protected]>2016-07-28 18:56:22 +0200
commit4fae16dffb812f0e0d98a0b2b0856ca48ca63e6c (patch)
treec661ae0eaa75eb0f4af66870bb0c34a5b1c4c273
parentcd894f149732a06ba4b2ccdc4cb86edf7ff68620 (diff)
timers/core: Correct callback order during CPU hot plug
On the tear-down path, the dead CPU callback for the timers was misplaced within the 'cpuhp_state' enumeration. There is a hidden dependency between the timers and block multiqueue. The timers callback must happen before the block multiqueue callback otherwise a RCU stall occurs. Move the timers callback to the proper place in the state machine. Reported-and-tested-by: Jon Hunter <[email protected]> Reported-by: kbuild test robot <[email protected]> Fixes: 24f73b99716a ("timers/core: Convert to hotplug state machine") Signed-off-by: Richard Cochran <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Sebastian Andrzej Siewior <[email protected]> Cc: Rasmus Villemoes <[email protected]> Cc: John Stultz <[email protected]> Cc: [email protected] Cc: Oleg Nesterov <[email protected]> Cc: Linus Torvalds <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Ingo Molnar <[email protected]>
-rw-r--r--include/linux/cpuhotplug.h2
-rw-r--r--kernel/cpu.c15
2 files changed, 11 insertions, 6 deletions
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 6d405db6fb12..242bf530edfc 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -20,9 +20,9 @@ enum cpuhp_state {
CPUHP_PROFILE_PREPARE,
CPUHP_X2APIC_PREPARE,
CPUHP_SMPCFD_PREPARE,
- CPUHP_TIMERS_DEAD,
CPUHP_RCUTREE_PREP,
CPUHP_NOTIFY_PREPARE,
+ CPUHP_TIMERS_DEAD,
CPUHP_BRINGUP_CPU,
CPUHP_AP_IDLE_DEAD,
CPUHP_AP_OFFLINE,
diff --git a/kernel/cpu.c b/kernel/cpu.c
index f24f45915b54..341bf80f80bd 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1200,11 +1200,6 @@ static struct cpuhp_step cpuhp_bp_states[] = {
.startup = smpcfd_prepare_cpu,
.teardown = smpcfd_dead_cpu,
},
- [CPUHP_TIMERS_DEAD] = {
- .name = "timers dead",
- .startup = NULL,
- .teardown = timers_dead_cpu,
- },
[CPUHP_RCUTREE_PREP] = {
.name = "RCU-tree prepare",
.startup = rcutree_prepare_cpu,
@@ -1221,6 +1216,16 @@ static struct cpuhp_step cpuhp_bp_states[] = {
.skip_onerr = true,
.cant_stop = true,
},
+ /*
+ * On the tear-down path, timers_dead_cpu() must be invoked
+ * before blk_mq_queue_reinit_notify() from notify_dead(),
+ * otherwise a RCU stall occurs.
+ */
+ [CPUHP_TIMERS_DEAD] = {
+ .name = "timers dead",
+ .startup = NULL,
+ .teardown = timers_dead_cpu,
+ },
/* Kicks the plugged cpu into life */
[CPUHP_BRINGUP_CPU] = {
.name = "cpu:bringup",