summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-08-26 23:32:41 +0400
committerIngo Molnar <mingo@kernel.org>2014-08-26 23:32:41 +0400
commit42594970022d223bf8f30d3aa22819e24779d6f6 (patch)
tree6b55f82a1fb1bb5dbb5ff61f90c41f7caa6a1f9b /kernel
parent52addcf9d6669fa439387610bc65c92fa0980cef (diff)
parent2a16fc93d2c9568e16d45db77c7b5f15e1921cf1 (diff)
downloadlinux-42594970022d223bf8f30d3aa22819e24779d6f6.tar.xz
Merge branch 'nohz/drop-double-write-v3' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks into timers/core
Pull nohz fixes from Frederic Weisbecker: " The tick reschedules itself unconditionally. It's relevant in periodic mode but not in dynticks mode where it results in spurious double clock writes and even spurious periodic behaviour for low-res case. This set fixes that: * 1st patch removes low-res periodic tick rescheduling in nohz mode. This fixes spurious periodic behaviour. * 2nd patch does the same for high-res mode. Here there is no such spurious periodic behaviour but it still spares a double clock write in some cases. " Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/time/tick-sched.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 99aa6ee3908f..cc0a5b6f741b 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -968,6 +968,10 @@ static void tick_nohz_handler(struct clock_event_device *dev)
tick_sched_do_timer(now);
tick_sched_handle(ts, regs);
+ /* No need to reprogram if we are running tickless */
+ if (unlikely(ts->tick_stopped))
+ return;
+
while (tick_nohz_reprogram(ts, now)) {
now = ktime_get();
tick_do_update_jiffies64(now);
@@ -1095,6 +1099,10 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
if (regs)
tick_sched_handle(ts, regs);
+ /* No need to reprogram if we are in idle or full dynticks mode */
+ if (unlikely(ts->tick_stopped))
+ return HRTIMER_NORESTART;
+
hrtimer_forward(timer, now, tick_period);
return HRTIMER_RESTART;