Skip to content

Commit 24f73b9

Browse files
Richard CochranIngo Molnar
authored andcommitted
timers/core: Convert to hotplug state machine
When tearing down, call timers_dead_cpu() before notify_dead(). There is a hidden dependency between: - timers - block multiqueue - rcutree If timers_dead_cpu() comes later than blk_mq_queue_reinit_notify() that latter function causes a RCU stall. Signed-off-by: Richard Cochran <rcochran@linutronix.de> Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: John Stultz <john.stultz@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160713153337.566790058@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 27590dc commit 24f73b9

File tree

4 files changed

+14
-23
lines changed

4 files changed

+14
-23
lines changed

include/linux/cpuhotplug.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ enum cpuhp_state {
1616
CPUHP_X86_APB_DEAD,
1717
CPUHP_WORKQUEUE_PREP,
1818
CPUHP_HRTIMERS_PREPARE,
19+
CPUHP_TIMERS_DEAD,
1920
CPUHP_NOTIFY_PREPARE,
2021
CPUHP_BRINGUP_CPU,
2122
CPUHP_AP_IDLE_DEAD,

include/linux/timer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,4 +273,10 @@ unsigned long __round_jiffies_up_relative(unsigned long j, int cpu);
273273
unsigned long round_jiffies_up(unsigned long j);
274274
unsigned long round_jiffies_up_relative(unsigned long j);
275275

276+
#ifdef CONFIG_HOTPLUG_CPU
277+
int timers_dead_cpu(unsigned int cpu);
278+
#else
279+
#define timers_dead_cpu NULL
280+
#endif
281+
276282
#endif

kernel/cpu.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
11951195
.startup = hrtimers_prepare_cpu,
11961196
.teardown = hrtimers_dead_cpu,
11971197
},
1198+
[CPUHP_TIMERS_DEAD] = {
1199+
.name = "timers dead",
1200+
.startup = NULL,
1201+
.teardown = timers_dead_cpu,
1202+
},
11981203
/*
11991204
* Preparatory and dead notifiers. Will be replaced once the notifiers
12001205
* are converted to states.

kernel/time/timer.c

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,7 +1804,7 @@ static void migrate_timer_list(struct timer_base *new_base, struct hlist_head *h
18041804
}
18051805
}
18061806

1807-
static void migrate_timers(int cpu)
1807+
int timers_dead_cpu(unsigned int cpu)
18081808
{
18091809
struct timer_base *old_base;
18101810
struct timer_base *new_base;
@@ -1831,29 +1831,9 @@ static void migrate_timers(int cpu)
18311831
spin_unlock_irq(&new_base->lock);
18321832
put_cpu_ptr(&timer_bases);
18331833
}
1834+
return 0;
18341835
}
18351836

1836-
static int timer_cpu_notify(struct notifier_block *self,
1837-
unsigned long action, void *hcpu)
1838-
{
1839-
switch (action) {
1840-
case CPU_DEAD:
1841-
case CPU_DEAD_FROZEN:
1842-
migrate_timers((long)hcpu);
1843-
break;
1844-
default:
1845-
break;
1846-
}
1847-
1848-
return NOTIFY_OK;
1849-
}
1850-
1851-
static inline void timer_register_cpu_notifier(void)
1852-
{
1853-
cpu_notifier(timer_cpu_notify, 0);
1854-
}
1855-
#else
1856-
static inline void timer_register_cpu_notifier(void) { }
18571837
#endif /* CONFIG_HOTPLUG_CPU */
18581838

18591839
static void __init init_timer_cpu(int cpu)
@@ -1881,7 +1861,6 @@ void __init init_timers(void)
18811861
{
18821862
init_timer_cpus();
18831863
init_timer_stats();
1884-
timer_register_cpu_notifier();
18851864
open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
18861865
}
18871866

0 commit comments

Comments
 (0)