hrtimer: Convert to hotplug state machine
authorThomas Gleixner <tglx@linutronix.de>
Fri, 15 Jul 2016 08:41:04 +0000 (10:41 +0200)
committerIngo Molnar <mingo@kernel.org>
Fri, 15 Jul 2016 08:41:37 +0000 (10:41 +0200)
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>
include/linux/cpuhotplug.h
include/linux/hrtimer.h
kernel/cpu.c
kernel/time/hrtimer.c

index 070cc7f2886220b5c2820fc210d2cc9af6f9de00..04ecc55009ed089587d0e8b2dbda7f5786b1bac9 100644 (file)
@@ -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,
index c98c6539e2c2d40cf6a134b7fb33c50accc90d76..5e00f80b1535e6b7487c1fbcd0949fad42bfea2e 100644 (file)
@@ -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
index af53f820fec9900cbffcca30a1f8ca3a24c67891..85500e7fe238732e3ff27f84019e6cdf83c918bb 100644 (file)
@@ -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.
index d13c9aebf7a3b7e955b897f30f749dc0907f15dc..9ba7c820fc231b2bfef4dd94228dbb6cf8c6f877 100644 (file)
@@ -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());
 }
 
 /**