summaryrefslogtreecommitdiff
path: root/kernel/time
diff options
context:
space:
mode:
authorNeeraj Upadhyay <neeraju@codeaurora.org>2017-05-03 16:05:48 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-05-15 00:06:22 -0700
commit1ef28deec05881286bfe2cabe835f9a7c7e1bd6b (patch)
tree54e195cba820cf2700ade457161ba66f6969c433 /kernel/time
parentc6d1c1699e7dcc7ec170baae48be94814061d0b7 (diff)
timer: Clear deferrable_pending while handling timer softirq
Clear deferrable_pending everytime timer softirq is run. This handles a potential race condition, where one CPU handles all deferrable timers, before the other CPU gets a change to run timer softirq. Due to the deferrable_pending not getting cleared, subsequently, CPUs do not raise the softirq for handling expired deferrable timers, in nohz idle enter path. Change-Id: Ie5fd78f9b27e7553ba43101b86ad939c289827e0 Signed-off-by: Neeraj Upadhyay <neeraju@codeaurora.org>
Diffstat (limited to 'kernel/time')
-rw-r--r--kernel/time/timer.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 8315d4d72cc3..75ce9cbc313d 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -151,10 +151,11 @@ static inline struct tvec_base *get_target_base(struct tvec_base *base,
static inline void __run_deferrable_timers(void)
{
- if (time_after_eq(jiffies, tvec_base_deferrable.timer_jiffies)) {
- if ((atomic_cmpxchg(&deferrable_pending, 1, 0) &&
- tick_do_timer_cpu == TICK_DO_TIMER_NONE) ||
- tick_do_timer_cpu == smp_processor_id())
+ if ((atomic_cmpxchg(&deferrable_pending, 1, 0) &&
+ tick_do_timer_cpu == TICK_DO_TIMER_NONE) ||
+ tick_do_timer_cpu == smp_processor_id()) {
+ if (time_after_eq(jiffies,
+ tvec_base_deferrable.timer_jiffies))
__run_timers(&tvec_base_deferrable);
}
}