aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-07-15 04:41:04 -0400
committerIngo Molnar <mingo@kernel.org>2016-07-15 04:41:37 -0400
commit27590dc17b34aedc4f3e14bd107ee59b9db9b0a6 (patch)
tree497208a2586ac32c9bea908e04fecadd553cfd5e
parentae6a8a2ed721ecdbc15d32b2089af5ed2190adc7 (diff)
hrtimer: Convert to hotplug state machine
Split out the clockevents callbacks instead of piggybacking them on hrtimers. This gets rid of a POST_DEAD user. See commit: 54e88fad223c ("sched: Make sure timers have migrated before killing the migration_thread") We just move the callback state to the proper place in the state machine. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> 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: Rusty Russell <rusty@rustcorp.com.au> Cc: rt@linutronix.de Link: http://lkml.kernel.org/r/20160713153337.485419196@linutronix.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--include/linux/cpuhotplug.h1
-rw-r--r--include/linux/hrtimer.h7
-rw-r--r--kernel/cpu.c5
-rw-r--r--kernel/time/hrtimer.c40
4 files changed, 18 insertions, 35 deletions
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 070cc7f28862..04ecc55009ed 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -15,6 +15,7 @@ enum cpuhp_state {
15 CPUHP_X86_HPET_DEAD, 15 CPUHP_X86_HPET_DEAD,
16 CPUHP_X86_APB_DEAD, 16 CPUHP_X86_APB_DEAD,
17 CPUHP_WORKQUEUE_PREP, 17 CPUHP_WORKQUEUE_PREP,
18 CPUHP_HRTIMERS_PREPARE,
18 CPUHP_NOTIFY_PREPARE, 19 CPUHP_NOTIFY_PREPARE,
19 CPUHP_BRINGUP_CPU, 20 CPUHP_BRINGUP_CPU,
20 CPUHP_AP_IDLE_DEAD, 21 CPUHP_AP_IDLE_DEAD,
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index c98c6539e2c2..5e00f80b1535 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -494,4 +494,11 @@ extern void __init hrtimers_init(void);
494/* Show pending timers: */ 494/* Show pending timers: */
495extern void sysrq_timer_list_show(void); 495extern void sysrq_timer_list_show(void);
496 496
497int hrtimers_prepare_cpu(unsigned int cpu);
498#ifdef CONFIG_HOTPLUG_CPU
499int hrtimers_dead_cpu(unsigned int cpu);
500#else
501#define hrtimers_dead_cpu NULL
502#endif
503
497#endif 504#endif
diff --git a/kernel/cpu.c b/kernel/cpu.c
index af53f820fec9..85500e7fe238 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1190,6 +1190,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
1190 .startup = workqueue_prepare_cpu, 1190 .startup = workqueue_prepare_cpu,
1191 .teardown = NULL, 1191 .teardown = NULL,
1192 }, 1192 },
1193 [CPUHP_HRTIMERS_PREPARE] = {
1194 .name = "hrtimers prepare",
1195 .startup = hrtimers_prepare_cpu,
1196 .teardown = hrtimers_dead_cpu,
1197 },
1193 /* 1198 /*
1194 * Preparatory and dead notifiers. Will be replaced once the notifiers 1199 * Preparatory and dead notifiers. Will be replaced once the notifiers
1195 * are converted to states. 1200 * are converted to states.
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index d13c9aebf7a3..9ba7c820fc23 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1590,7 +1590,7 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
1590/* 1590/*
1591 * Functions related to boot-time initialization: 1591 * Functions related to boot-time initialization:
1592 */ 1592 */
1593static void init_hrtimers_cpu(int cpu) 1593int hrtimers_prepare_cpu(unsigned int cpu)
1594{ 1594{
1595 struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu); 1595 struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
1596 int i; 1596 int i;
@@ -1602,6 +1602,7 @@ static void init_hrtimers_cpu(int cpu)
1602 1602
1603 cpu_base->cpu = cpu; 1603 cpu_base->cpu = cpu;
1604 hrtimer_init_hres(cpu_base); 1604 hrtimer_init_hres(cpu_base);
1605 return 0;
1605} 1606}
1606 1607
1607#ifdef CONFIG_HOTPLUG_CPU 1608#ifdef CONFIG_HOTPLUG_CPU
@@ -1636,7 +1637,7 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
1636 } 1637 }
1637} 1638}
1638 1639
1639static void migrate_hrtimers(int scpu) 1640int hrtimers_dead_cpu(unsigned int scpu)
1640{ 1641{
1641 struct hrtimer_cpu_base *old_base, *new_base; 1642 struct hrtimer_cpu_base *old_base, *new_base;
1642 int i; 1643 int i;
@@ -1665,45 +1666,14 @@ static void migrate_hrtimers(int scpu)
1665 /* Check, if we got expired work to do */ 1666 /* Check, if we got expired work to do */
1666 __hrtimer_peek_ahead_timers(); 1667 __hrtimer_peek_ahead_timers();
1667 local_irq_enable(); 1668 local_irq_enable();
1669 return 0;
1668} 1670}
1669 1671
1670#endif /* CONFIG_HOTPLUG_CPU */ 1672#endif /* CONFIG_HOTPLUG_CPU */
1671 1673
1672static int hrtimer_cpu_notify(struct notifier_block *self,
1673 unsigned long action, void *hcpu)
1674{
1675 int scpu = (long)hcpu;
1676
1677 switch (action) {
1678
1679 case CPU_UP_PREPARE:
1680 case CPU_UP_PREPARE_FROZEN:
1681 init_hrtimers_cpu(scpu);
1682 break;
1683
1684#ifdef CONFIG_HOTPLUG_CPU
1685 case CPU_DEAD:
1686 case CPU_DEAD_FROZEN:
1687 migrate_hrtimers(scpu);
1688 break;
1689#endif
1690
1691 default:
1692 break;
1693 }
1694
1695 return NOTIFY_OK;
1696}
1697
1698static struct notifier_block hrtimers_nb = {
1699 .notifier_call = hrtimer_cpu_notify,
1700};
1701
1702void __init hrtimers_init(void) 1674void __init hrtimers_init(void)
1703{ 1675{
1704 hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE, 1676 hrtimers_prepare_cpu(smp_processor_id());
1705 (void *)(long)smp_processor_id());
1706 register_cpu_notifier(&hrtimers_nb);
1707} 1677}
1708 1678
1709/** 1679/**