aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/timer.c')
-rw-r--r--kernel/timer.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/kernel/timer.c b/kernel/timer.c
index 797cccb86431..dd6c2c1c561b 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -695,15 +695,28 @@ static unsigned long cmp_next_hrtimer_event(unsigned long now,
695{ 695{
696 ktime_t hr_delta = hrtimer_get_next_event(); 696 ktime_t hr_delta = hrtimer_get_next_event();
697 struct timespec tsdelta; 697 struct timespec tsdelta;
698 unsigned long delta;
698 699
699 if (hr_delta.tv64 == KTIME_MAX) 700 if (hr_delta.tv64 == KTIME_MAX)
700 return expires; 701 return expires;
701 702
702 if (hr_delta.tv64 <= TICK_NSEC) 703 /*
703 return now; 704 * Expired timer available, let it expire in the next tick
705 */
706 if (hr_delta.tv64 <= 0)
707 return now + 1;
704 708
705 tsdelta = ktime_to_timespec(hr_delta); 709 tsdelta = ktime_to_timespec(hr_delta);
706 now += timespec_to_jiffies(&tsdelta); 710 delta = timespec_to_jiffies(&tsdelta);
711 /*
712 * Take rounding errors in to account and make sure, that it
713 * expires in the next tick. Otherwise we go into an endless
714 * ping pong due to tick_nohz_stop_sched_tick() retriggering
715 * the timer softirq
716 */
717 if (delta < 1)
718 delta = 1;
719 now += delta;
707 if (time_before(now, expires)) 720 if (time_before(now, expires))
708 return now; 721 return now;
709 return expires; 722 return expires;
@@ -1003,7 +1016,7 @@ static int timekeeping_resume(struct sys_device *dev)
1003 clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); 1016 clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL);
1004 1017
1005 /* Resume hrtimers */ 1018 /* Resume hrtimers */
1006 clock_was_set(); 1019 hres_timers_resume();
1007 1020
1008 return 0; 1021 return 0;
1009} 1022}