diff options
Diffstat (limited to 'kernel/time/tick-broadcast.c')
| -rw-r--r-- | kernel/time/tick-broadcast.c | 48 |
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); | |||
| 36 | static void tick_broadcast_setup_oneshot(struct clock_event_device *bc); | 36 | static void tick_broadcast_setup_oneshot(struct clock_event_device *bc); |
| 37 | static void tick_broadcast_clear_oneshot(int cpu); | 37 | static void tick_broadcast_clear_oneshot(int cpu); |
| 38 | static void tick_resume_broadcast_oneshot(struct clock_event_device *bc); | 38 | static void tick_resume_broadcast_oneshot(struct clock_event_device *bc); |
| 39 | # ifdef CONFIG_HOTPLUG_CPU | ||
| 40 | static void tick_broadcast_oneshot_offline(unsigned int cpu); | ||
| 41 | # endif | ||
| 39 | #else | 42 | #else |
| 40 | static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); } | 43 | static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { BUG(); } |
| 41 | static inline void tick_broadcast_clear_oneshot(int cpu) { } | 44 | static inline void tick_broadcast_clear_oneshot(int cpu) { } |
| 42 | static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { } | 45 | static inline void tick_resume_broadcast_oneshot(struct clock_event_device *bc) { } |
| 46 | # ifdef CONFIG_HOTPLUG_CPU | ||
| 47 | static 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 | /* | 442 | static void tick_shutdown_broadcast(void) |
| 437 | * Remove a CPU from broadcasting | ||
| 438 | */ | ||
| 439 | void 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 | */ | ||
| 455 | void 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 | ||
| 459 | void tick_suspend_broadcast(void) | 467 | void 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 | */ |
| 955 | void tick_shutdown_broadcast_oneshot(unsigned int cpu) | 963 | static 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 | ||
