diff options
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 21 |
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 | } |
