diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index fe3a9a9f8328..bf7c4193b936 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -489,9 +489,21 @@ unsigned long next_timer_interrupt(void) | |||
489 | struct list_head *list; | 489 | struct list_head *list; |
490 | struct timer_list *nte; | 490 | struct timer_list *nte; |
491 | unsigned long expires; | 491 | unsigned long expires; |
492 | unsigned long hr_expires = MAX_JIFFY_OFFSET; | ||
493 | ktime_t hr_delta; | ||
492 | tvec_t *varray[4]; | 494 | tvec_t *varray[4]; |
493 | int i, j; | 495 | int i, j; |
494 | 496 | ||
497 | hr_delta = hrtimer_get_next_event(); | ||
498 | if (hr_delta.tv64 != KTIME_MAX) { | ||
499 | struct timespec tsdelta; | ||
500 | tsdelta = ktime_to_timespec(hr_delta); | ||
501 | hr_expires = timespec_to_jiffies(&tsdelta); | ||
502 | if (hr_expires < 3) | ||
503 | return hr_expires + jiffies; | ||
504 | } | ||
505 | hr_expires += jiffies; | ||
506 | |||
495 | base = &__get_cpu_var(tvec_bases); | 507 | base = &__get_cpu_var(tvec_bases); |
496 | spin_lock(&base->t_base.lock); | 508 | spin_lock(&base->t_base.lock); |
497 | expires = base->timer_jiffies + (LONG_MAX >> 1); | 509 | expires = base->timer_jiffies + (LONG_MAX >> 1); |
@@ -542,6 +554,10 @@ found: | |||
542 | } | 554 | } |
543 | } | 555 | } |
544 | spin_unlock(&base->t_base.lock); | 556 | spin_unlock(&base->t_base.lock); |
557 | |||
558 | if (time_before(hr_expires, expires)) | ||
559 | return hr_expires; | ||
560 | |||
545 | return expires; | 561 | return expires; |
546 | } | 562 | } |
547 | #endif | 563 | #endif |
@@ -925,6 +941,8 @@ static inline void update_times(void) | |||
925 | void do_timer(struct pt_regs *regs) | 941 | void do_timer(struct pt_regs *regs) |
926 | { | 942 | { |
927 | jiffies_64++; | 943 | jiffies_64++; |
944 | /* prevent loading jiffies before storing new jiffies_64 value. */ | ||
945 | barrier(); | ||
928 | update_times(); | 946 | update_times(); |
929 | softlockup_tick(regs); | 947 | softlockup_tick(regs); |
930 | } | 948 | } |
@@ -1351,10 +1369,10 @@ static inline u64 time_interpolator_get_cycles(unsigned int src) | |||
1351 | return x(); | 1369 | return x(); |
1352 | 1370 | ||
1353 | case TIME_SOURCE_MMIO64 : | 1371 | case TIME_SOURCE_MMIO64 : |
1354 | return readq((void __iomem *) time_interpolator->addr); | 1372 | return readq_relaxed((void __iomem *)time_interpolator->addr); |
1355 | 1373 | ||
1356 | case TIME_SOURCE_MMIO32 : | 1374 | case TIME_SOURCE_MMIO32 : |
1357 | return readl((void __iomem *) time_interpolator->addr); | 1375 | return readl_relaxed((void __iomem *)time_interpolator->addr); |
1358 | 1376 | ||
1359 | default: return get_cycles(); | 1377 | default: return get_cycles(); |
1360 | } | 1378 | } |