aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-broadcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/tick-broadcast.c')
-rw-r--r--kernel/time/tick-broadcast.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index ee834d4fb814..e51778c312f1 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -36,10 +36,16 @@ static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
36static void tick_broadcast_setup_oneshot(struct clock_event_device *bc); 36static void tick_broadcast_setup_oneshot(struct clock_event_device *bc);
37static void tick_broadcast_clear_oneshot(int cpu); 37static void tick_broadcast_clear_oneshot(int cpu);
38static void tick_resume_broadcast_oneshot(struct clock_event_device *bc); 38static void tick_resume_broadcast_oneshot(struct clock_event_device *bc);
39# ifdef CONFIG_HOTPLUG_CPU
40static void tick_broadcast_oneshot_offline(unsigned int cpu);
41# endif
39#else 42#else
40static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); } 43static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); }
41static inline void tick_broadcast_clear_oneshot(int cpu) { } 44static inline void tick_broadcast_clear_oneshot(int cpu) { }
42static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { } 45static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { }
46# ifdef CONFIG_HOTPLUG_CPU
47static inline void tick_broadcast_oneshot_offline(unsigned int cpu) { }
48# endif
43#endif 49#endif
44 50
45/* 51/*
@@ -433,27 +439,29 @@ void tick_set_periodic_handler(struct clock_event_device *dev, int broadcast)
433} 439}
434 440
435#ifdef CONFIG_HOTPLUG_CPU 441#ifdef CONFIG_HOTPLUG_CPU
436/* 442static void tick_shutdown_broadcast(void)
437 * Remove a CPU from broadcasting
438 */
439void tick_shutdown_broadcast(unsigned int cpu)
440{ 443{
441 struct clock_event_device *bc; 444 struct clock_event_device *bc = tick_broadcast_device.evtdev;
442 unsigned long flags;
443
444 raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
445
446 bc = tick_broadcast_device.evtdev;
447 cpumask_clear_cpu(cpu, tick_broadcast_mask);
448 cpumask_clear_cpu(cpu, tick_broadcast_on);
449 445
450 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) { 446 if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) {
451 if (bc && cpumask_empty(tick_broadcast_mask)) 447 if (bc && cpumask_empty(tick_broadcast_mask))
452 clockevents_shutdown(bc); 448 clockevents_shutdown(bc);
453 } 449 }
450}
454 451
455 raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); 452/*
453 * Remove a CPU from broadcasting
454 */
455void tick_broadcast_offline(unsigned int cpu)
456{
457 raw_spin_lock(&tick_broadcast_lock);
458 cpumask_clear_cpu(cpu, tick_broadcast_mask);
459 cpumask_clear_cpu(cpu, tick_broadcast_on);
460 tick_broadcast_oneshot_offline(cpu);
461 tick_shutdown_broadcast();
462 raw_spin_unlock(&tick_broadcast_lock);
456} 463}
464
457#endif 465#endif
458 466
459void tick_suspend_broadcast(void) 467void tick_suspend_broadcast(void)
@@ -801,13 +809,13 @@ int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)
801 * either the CPU handling the broadcast 809 * either the CPU handling the broadcast
802 * interrupt or we got woken by something else. 810 * interrupt or we got woken by something else.
803 * 811 *
804 * We are not longer in the broadcast mask, so 812 * We are no longer in the broadcast mask, so
805 * if the cpu local expiry time is already 813 * if the cpu local expiry time is already
806 * reached, we would reprogram the cpu local 814 * reached, we would reprogram the cpu local
807 * timer with an already expired event. 815 * timer with an already expired event.
808 * 816 *
809 * This can lead to a ping-pong when we return 817 * This can lead to a ping-pong when we return
810 * to idle and therefor rearm the broadcast 818 * to idle and therefore rearm the broadcast
811 * timer before the cpu local timer was able 819 * timer before the cpu local timer was able
812 * to fire. This happens because the forced 820 * to fire. This happens because the forced
813 * reprogramming makes sure that the event 821 * reprogramming makes sure that the event
@@ -950,14 +958,10 @@ void hotplug_cpu__broadcast_tick_pull(int deadcpu)
950} 958}
951 959
952/* 960/*
953 * Remove a dead CPU from broadcasting 961 * Remove a dying CPU from broadcasting
954 */ 962 */
955void tick_shutdown_broadcast_oneshot(unsigned int cpu) 963static void tick_broadcast_oneshot_offline(unsigned int cpu)
956{ 964{
957 unsigned long flags;
958
959 raw_spin_lock_irqsave(&tick_broadcast_lock, flags);
960
961 /* 965 /*
962 * Clear the broadcast masks for the dead cpu, but do not stop 966 * Clear the broadcast masks for the dead cpu, but do not stop
963 * the broadcast device! 967 * the broadcast device!
@@ -965,8 +969,6 @@ void tick_shutdown_broadcast_oneshot(unsigned int cpu)
965 cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask); 969 cpumask_clear_cpu(cpu, tick_broadcast_oneshot_mask);
966 cpumask_clear_cpu(cpu, tick_broadcast_pending_mask); 970 cpumask_clear_cpu(cpu, tick_broadcast_pending_mask);
967 cpumask_clear_cpu(cpu, tick_broadcast_force_mask); 971 cpumask_clear_cpu(cpu, tick_broadcast_force_mask);
968
969 raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags);
970} 972}
971#endif 973#endif
972 974