When expiry is set to KTIME_MAX, we cancel the 'tick-sched' hrtimer in highres mode and skip reprogramming clockevent device in lowres mode. But, the clockevent device is already reprogrammed from tick-handler.
We will get interrupted atleast one more time.
In highres mode, as there is no hrtimer to service, hrtimer_interrupt() will return without calling tick-handler.
But the problem is somewhat bigger in lowres mode. We unconditionally reschedule tick everytime tick_nohz_handler() is called and so even if tick_stopped is set, we never enter full dynticks mode.
To fix this, skip rescheduling next tick from tick-handler when we are running tickless.
OTOH, when expires isn't equal to KTIME_MAX, we avoid reprogramming the clkdev from the tick when it is stopped because it's going to be reprogrammed from irq_exit() anyway. So we could avoid one useless device write.
Signed-off-by: Viresh Kumar viresh.kumar@linaro.org ---
kernel/time/tick-sched.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 6558b7a..a4a45e0 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -956,6 +956,12 @@ static void tick_nohz_handler(struct clock_event_device *dev) tick_sched_do_timer(now); tick_sched_handle(ts, regs);
+ /* + * Skip reprogramming next event if we are running tickless. + */ + if (ts->tick_stopped) + return; + while (tick_nohz_reprogram(ts, now)) { now = ktime_get(); tick_do_update_jiffies64(now);