[tip:smp/hotplug] hrtimer: Convert to hotplug state machine

From: tip-bot for Thomas Gleixner
Date: Tue Jul 19 2016 - 03:27:40 EST


Commit-ID: 27590dc17b34aedc4f3e14bd107ee59b9db9b0a6
Gitweb: http://git.kernel.org/tip/27590dc17b34aedc4f3e14bd107ee59b9db9b0a6
Author: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
AuthorDate: Fri, 15 Jul 2016 10:41:04 +0200
Committer: Ingo Molnar <mingo@xxxxxxxxxx>
CommitDate: Fri, 15 Jul 2016 10:41:37 +0200

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@xxxxxxxxxxxxx>
Signed-off-by: Anna-Maria Gleixner <anna-maria@xxxxxxxxxxxxx>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
Cc: Rusty Russell <rusty@xxxxxxxxxxxxxxx>
Cc: rt@xxxxxxxxxxxxx
Link: http://lkml.kernel.org/r/20160713153337.485419196@xxxxxxxxxxxxx
Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx>
---
include/linux/cpuhotplug.h | 1 +
include/linux/hrtimer.h | 7 +++++++
kernel/cpu.c | 5 +++++
kernel/time/hrtimer.c | 40 +++++-----------------------------------
4 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 070cc7f..04ecc55 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -15,6 +15,7 @@ enum cpuhp_state {
CPUHP_X86_HPET_DEAD,
CPUHP_X86_APB_DEAD,
CPUHP_WORKQUEUE_PREP,
+ CPUHP_HRTIMERS_PREPARE,
CPUHP_NOTIFY_PREPARE,
CPUHP_BRINGUP_CPU,
CPUHP_AP_IDLE_DEAD,
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index c98c653..5e00f80 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -494,4 +494,11 @@ extern void __init hrtimers_init(void);
/* Show pending timers: */
extern void sysrq_timer_list_show(void);

+int hrtimers_prepare_cpu(unsigned int cpu);
+#ifdef CONFIG_HOTPLUG_CPU
+int hrtimers_dead_cpu(unsigned int cpu);
+#else
+#define hrtimers_dead_cpu NULL
+#endif
+
#endif
diff --git a/kernel/cpu.c b/kernel/cpu.c
index af53f82..85500e7 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -1190,6 +1190,11 @@ static struct cpuhp_step cpuhp_bp_states[] = {
.startup = workqueue_prepare_cpu,
.teardown = NULL,
},
+ [CPUHP_HRTIMERS_PREPARE] = {
+ .name = "hrtimers prepare",
+ .startup = hrtimers_prepare_cpu,
+ .teardown = hrtimers_dead_cpu,
+ },
/*
* Preparatory and dead notifiers. Will be replaced once the notifiers
* are converted to states.
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index d13c9ae..9ba7c82 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1590,7 +1590,7 @@ SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
/*
* Functions related to boot-time initialization:
*/
-static void init_hrtimers_cpu(int cpu)
+int hrtimers_prepare_cpu(unsigned int cpu)
{
struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
int i;
@@ -1602,6 +1602,7 @@ static void init_hrtimers_cpu(int cpu)

cpu_base->cpu = cpu;
hrtimer_init_hres(cpu_base);
+ return 0;
}

#ifdef CONFIG_HOTPLUG_CPU
@@ -1636,7 +1637,7 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,
}
}

-static void migrate_hrtimers(int scpu)
+int hrtimers_dead_cpu(unsigned int scpu)
{
struct hrtimer_cpu_base *old_base, *new_base;
int i;
@@ -1665,45 +1666,14 @@ static void migrate_hrtimers(int scpu)
/* Check, if we got expired work to do */
__hrtimer_peek_ahead_timers();
local_irq_enable();
+ return 0;
}

#endif /* CONFIG_HOTPLUG_CPU */

-static int hrtimer_cpu_notify(struct notifier_block *self,
- unsigned long action, void *hcpu)
-{
- int scpu = (long)hcpu;
-
- switch (action) {
-
- case CPU_UP_PREPARE:
- case CPU_UP_PREPARE_FROZEN:
- init_hrtimers_cpu(scpu);
- break;
-
-#ifdef CONFIG_HOTPLUG_CPU
- case CPU_DEAD:
- case CPU_DEAD_FROZEN:
- migrate_hrtimers(scpu);
- break;
-#endif
-
- default:
- break;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block hrtimers_nb = {
- .notifier_call = hrtimer_cpu_notify,
-};
-
void __init hrtimers_init(void)
{
- hrtimer_cpu_notify(&hrtimers_nb, (unsigned long)CPU_UP_PREPARE,
- (void *)(long)smp_processor_id());
- register_cpu_notifier(&hrtimers_nb);
+ hrtimers_prepare_cpu(smp_processor_id());
}

/**