diff options
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index fe3a9a9f8328..2410c18dbeb1 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 | } |
| @@ -1336,8 +1354,8 @@ void __init init_timers(void) | |||
| 1336 | 1354 | ||
| 1337 | #ifdef CONFIG_TIME_INTERPOLATION | 1355 | #ifdef CONFIG_TIME_INTERPOLATION |
| 1338 | 1356 | ||
| 1339 | struct time_interpolator *time_interpolator; | 1357 | struct time_interpolator *time_interpolator __read_mostly; |
| 1340 | static struct time_interpolator *time_interpolator_list; | 1358 | static struct time_interpolator *time_interpolator_list __read_mostly; |
| 1341 | static DEFINE_SPINLOCK(time_interpolator_lock); | 1359 | static DEFINE_SPINLOCK(time_interpolator_lock); |
| 1342 | 1360 | ||
| 1343 | static inline u64 time_interpolator_get_cycles(unsigned int src) | 1361 | static inline u64 time_interpolator_get_cycles(unsigned int src) |
| @@ -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 | } |
