diff options
author | Neeraj Upadhyay <neeraju@codeaurora.org> | 2017-05-03 16:05:48 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-05-15 00:06:22 -0700 |
commit | 1ef28deec05881286bfe2cabe835f9a7c7e1bd6b (patch) | |
tree | 54e195cba820cf2700ade457161ba66f6969c433 /kernel/time | |
parent | c6d1c1699e7dcc7ec170baae48be94814061d0b7 (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.c | 9 |
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); } } |