diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2015-04-02 20:37:24 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-04-03 02:44:36 -0400 |
commit | 52c063d1adbc16c76e70fffa20727fcd4e9343b3 (patch) | |
tree | 08e2f8c56e9e972082adbeda1fe3cff646a45f4e | |
parent | ffa48c0d76803057ee89bf220305466d74256d7b (diff) |
clockevents: Make tick handover explicit
clockevents_notify() is a leftover from the early design of the
clockevents facility. It's really not a notification mechanism,
it's a multiplex call. We are way better off to have explicit
calls instead of this monstrosity.
Split out the tick_handover call and invoke it explicitely from
the hotplug code. Temporary solution will be cleaned up in later
patches.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[ Rebase ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: http://lkml.kernel.org/r/1658173.RkEEILFiQZ@vostro.rjw.lan
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | include/linux/clockchips.h | 1 | ||||
-rw-r--r-- | include/linux/tick.h | 2 | ||||
-rw-r--r-- | kernel/cpu.c | 2 | ||||
-rw-r--r-- | kernel/time/clockevents.c | 4 | ||||
-rw-r--r-- | kernel/time/hrtimer.c | 4 | ||||
-rw-r--r-- | kernel/time/tick-common.c | 9 | ||||
-rw-r--r-- | kernel/time/tick-internal.h | 1 |
7 files changed, 10 insertions, 13 deletions
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h index f97f498a5d10..f4bde22f8a05 100644 --- a/include/linux/clockchips.h +++ b/include/linux/clockchips.h | |||
@@ -11,7 +11,6 @@ | |||
11 | /* Clock event notification values */ | 11 | /* Clock event notification values */ |
12 | enum clock_event_nofitiers { | 12 | enum clock_event_nofitiers { |
13 | CLOCK_EVT_NOTIFY_ADD, | 13 | CLOCK_EVT_NOTIFY_ADD, |
14 | CLOCK_EVT_NOTIFY_CPU_DYING, | ||
15 | CLOCK_EVT_NOTIFY_CPU_DEAD, | 14 | CLOCK_EVT_NOTIFY_CPU_DEAD, |
16 | }; | 15 | }; |
17 | 16 | ||
diff --git a/include/linux/tick.h b/include/linux/tick.h index 6119321fc3be..2c68fa3b9436 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h | |||
@@ -19,12 +19,14 @@ extern void tick_unfreeze(void); | |||
19 | extern void tick_suspend_local(void); | 19 | extern void tick_suspend_local(void); |
20 | /* Should be core only, but XEN resume magic and ARM BL switcher require it */ | 20 | /* Should be core only, but XEN resume magic and ARM BL switcher require it */ |
21 | extern void tick_resume_local(void); | 21 | extern void tick_resume_local(void); |
22 | extern void tick_handover_do_timer(void); | ||
22 | #else /* CONFIG_GENERIC_CLOCKEVENTS */ | 23 | #else /* CONFIG_GENERIC_CLOCKEVENTS */ |
23 | static inline void tick_init(void) { } | 24 | static inline void tick_init(void) { } |
24 | static inline void tick_freeze(void) { } | 25 | static inline void tick_freeze(void) { } |
25 | static inline void tick_unfreeze(void) { } | 26 | static inline void tick_unfreeze(void) { } |
26 | static inline void tick_suspend_local(void) { } | 27 | static inline void tick_suspend_local(void) { } |
27 | static inline void tick_resume_local(void) { } | 28 | static inline void tick_resume_local(void) { } |
29 | static inline void tick_handover_do_timer(void) { } | ||
28 | #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ | 30 | #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ |
29 | 31 | ||
30 | #ifdef CONFIG_TICK_ONESHOT | 32 | #ifdef CONFIG_TICK_ONESHOT |
diff --git a/kernel/cpu.c b/kernel/cpu.c index af5db20e5803..eba7eaa1341d 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -339,6 +339,8 @@ static int __ref take_cpu_down(void *_param) | |||
339 | return err; | 339 | return err; |
340 | 340 | ||
341 | cpu_notify(CPU_DYING | param->mod, param->hcpu); | 341 | cpu_notify(CPU_DYING | param->mod, param->hcpu); |
342 | /* Give up timekeeping duties */ | ||
343 | tick_handover_do_timer(); | ||
342 | /* Park the stopper thread */ | 344 | /* Park the stopper thread */ |
343 | kthread_park(current); | 345 | kthread_park(current); |
344 | return 0; | 346 | return 0; |
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index be9abf32c0b9..88fb3b96c7cc 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c | |||
@@ -655,10 +655,6 @@ int clockevents_notify(unsigned long reason, void *arg) | |||
655 | raw_spin_lock_irqsave(&clockevents_lock, flags); | 655 | raw_spin_lock_irqsave(&clockevents_lock, flags); |
656 | 656 | ||
657 | switch (reason) { | 657 | switch (reason) { |
658 | case CLOCK_EVT_NOTIFY_CPU_DYING: | ||
659 | tick_handover_do_timer(arg); | ||
660 | break; | ||
661 | |||
662 | case CLOCK_EVT_NOTIFY_CPU_DEAD: | 658 | case CLOCK_EVT_NOTIFY_CPU_DEAD: |
663 | tick_shutdown_broadcast_oneshot(arg); | 659 | tick_shutdown_broadcast_oneshot(arg); |
664 | tick_shutdown_broadcast(arg); | 660 | tick_shutdown_broadcast(arg); |
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index 721d29b99d10..6a7a64ec7d1b 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c | |||
@@ -1707,10 +1707,6 @@ static int hrtimer_cpu_notify(struct notifier_block *self, | |||
1707 | break; | 1707 | break; |
1708 | 1708 | ||
1709 | #ifdef CONFIG_HOTPLUG_CPU | 1709 | #ifdef CONFIG_HOTPLUG_CPU |
1710 | case CPU_DYING: | ||
1711 | case CPU_DYING_FROZEN: | ||
1712 | clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DYING, &scpu); | ||
1713 | break; | ||
1714 | case CPU_DEAD: | 1710 | case CPU_DEAD: |
1715 | case CPU_DEAD_FROZEN: | 1711 | case CPU_DEAD_FROZEN: |
1716 | { | 1712 | { |
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index e28ba5c044c5..055c868f3ec9 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c | |||
@@ -332,20 +332,23 @@ out_bc: | |||
332 | tick_install_broadcast_device(newdev); | 332 | tick_install_broadcast_device(newdev); |
333 | } | 333 | } |
334 | 334 | ||
335 | #ifdef CONFIG_HOTPLUG_CPU | ||
335 | /* | 336 | /* |
336 | * Transfer the do_timer job away from a dying cpu. | 337 | * Transfer the do_timer job away from a dying cpu. |
337 | * | 338 | * |
338 | * Called with interrupts disabled. | 339 | * Called with interrupts disabled. Not locking required. If |
340 | * tick_do_timer_cpu is owned by this cpu, nothing can change it. | ||
339 | */ | 341 | */ |
340 | void tick_handover_do_timer(int *cpup) | 342 | void tick_handover_do_timer(void) |
341 | { | 343 | { |
342 | if (*cpup == tick_do_timer_cpu) { | 344 | if (tick_do_timer_cpu == smp_processor_id()) { |
343 | int cpu = cpumask_first(cpu_online_mask); | 345 | int cpu = cpumask_first(cpu_online_mask); |
344 | 346 | ||
345 | tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu : | 347 | tick_do_timer_cpu = (cpu < nr_cpu_ids) ? cpu : |
346 | TICK_DO_TIMER_NONE; | 348 | TICK_DO_TIMER_NONE; |
347 | } | 349 | } |
348 | } | 350 | } |
351 | #endif | ||
349 | 352 | ||
350 | /* | 353 | /* |
351 | * Shutdown an event device on a given cpu: | 354 | * Shutdown an event device on a given cpu: |
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index 0266f9dbd114..aabcb5d00cf2 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h | |||
@@ -20,7 +20,6 @@ extern int tick_do_timer_cpu __read_mostly; | |||
20 | extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); | 20 | extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast); |
21 | extern void tick_handle_periodic(struct clock_event_device *dev); | 21 | extern void tick_handle_periodic(struct clock_event_device *dev); |
22 | extern void tick_check_new_device(struct clock_event_device *dev); | 22 | extern void tick_check_new_device(struct clock_event_device *dev); |
23 | extern void tick_handover_do_timer(int *cpup); | ||
24 | extern void tick_shutdown(unsigned int *cpup); | 23 | extern void tick_shutdown(unsigned int *cpup); |
25 | extern void tick_suspend(void); | 24 | extern void tick_suspend(void); |
26 | extern void tick_resume(void); | 25 | extern void tick_resume(void); |