diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 4f1cb0ab5251..2410c18dbeb1 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -489,13 +489,25 @@ 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); |
498 | list = 0; | 510 | list = NULL; |
499 | 511 | ||
500 | /* Look for timer events in tv1. */ | 512 | /* Look for timer events in tv1. */ |
501 | j = base->timer_jiffies & TVR_MASK; | 513 | j = base->timer_jiffies & TVR_MASK; |
@@ -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 |
@@ -717,12 +733,16 @@ static void second_overflow(void) | |||
717 | #endif | 733 | #endif |
718 | } | 734 | } |
719 | 735 | ||
720 | /* in the NTP reference this is called "hardclock()" */ | 736 | /* |
721 | static void update_wall_time_one_tick(void) | 737 | * Returns how many microseconds we need to add to xtime this tick |
738 | * in doing an adjustment requested with adjtime. | ||
739 | */ | ||
740 | static long adjtime_adjustment(void) | ||
722 | { | 741 | { |
723 | long time_adjust_step, delta_nsec; | 742 | long time_adjust_step; |
724 | 743 | ||
725 | if ((time_adjust_step = time_adjust) != 0 ) { | 744 | time_adjust_step = time_adjust; |
745 | if (time_adjust_step) { | ||
726 | /* | 746 | /* |
727 | * We are doing an adjtime thing. Prepare time_adjust_step to | 747 | * We are doing an adjtime thing. Prepare time_adjust_step to |
728 | * be within bounds. Note that a positive time_adjust means we | 748 | * be within bounds. Note that a positive time_adjust means we |
@@ -733,10 +753,19 @@ static void update_wall_time_one_tick(void) | |||
733 | */ | 753 | */ |
734 | time_adjust_step = min(time_adjust_step, (long)tickadj); | 754 | time_adjust_step = min(time_adjust_step, (long)tickadj); |
735 | time_adjust_step = max(time_adjust_step, (long)-tickadj); | 755 | time_adjust_step = max(time_adjust_step, (long)-tickadj); |
756 | } | ||
757 | return time_adjust_step; | ||
758 | } | ||
736 | 759 | ||
760 | /* in the NTP reference this is called "hardclock()" */ | ||
761 | static void update_wall_time_one_tick(void) | ||
762 | { | ||
763 | long time_adjust_step, delta_nsec; | ||
764 | |||
765 | time_adjust_step = adjtime_adjustment(); | ||
766 | if (time_adjust_step) | ||
737 | /* Reduce by this step the amount of time left */ | 767 | /* Reduce by this step the amount of time left */ |
738 | time_adjust -= time_adjust_step; | 768 | time_adjust -= time_adjust_step; |
739 | } | ||
740 | delta_nsec = tick_nsec + time_adjust_step * 1000; | 769 | delta_nsec = tick_nsec + time_adjust_step * 1000; |
741 | /* | 770 | /* |
742 | * Advance the phase, once it gets to one microsecond, then | 771 | * Advance the phase, once it gets to one microsecond, then |
@@ -759,6 +788,22 @@ static void update_wall_time_one_tick(void) | |||
759 | } | 788 | } |
760 | 789 | ||
761 | /* | 790 | /* |
791 | * Return how long ticks are at the moment, that is, how much time | ||
792 | * update_wall_time_one_tick will add to xtime next time we call it | ||
793 | * (assuming no calls to do_adjtimex in the meantime). | ||
794 | * The return value is in fixed-point nanoseconds with SHIFT_SCALE-10 | ||
795 | * bits to the right of the binary point. | ||
796 | * This function has no side-effects. | ||
797 | */ | ||
798 | u64 current_tick_length(void) | ||
799 | { | ||
800 | long delta_nsec; | ||
801 | |||
802 | delta_nsec = tick_nsec + adjtime_adjustment() * 1000; | ||
803 | return ((u64) delta_nsec << (SHIFT_SCALE - 10)) + time_adj; | ||
804 | } | ||
805 | |||
806 | /* | ||
762 | * Using a loop looks inefficient, but "ticks" is | 807 | * Using a loop looks inefficient, but "ticks" is |
763 | * usually just one (we shouldn't be losing ticks, | 808 | * usually just one (we shouldn't be losing ticks, |
764 | * we're doing this this way mainly for interrupt | 809 | * we're doing this this way mainly for interrupt |
@@ -896,6 +941,8 @@ static inline void update_times(void) | |||
896 | void do_timer(struct pt_regs *regs) | 941 | void do_timer(struct pt_regs *regs) |
897 | { | 942 | { |
898 | jiffies_64++; | 943 | jiffies_64++; |
944 | /* prevent loading jiffies before storing new jiffies_64 value. */ | ||
945 | barrier(); | ||
899 | update_times(); | 946 | update_times(); |
900 | softlockup_tick(regs); | 947 | softlockup_tick(regs); |
901 | } | 948 | } |
@@ -1307,8 +1354,8 @@ void __init init_timers(void) | |||
1307 | 1354 | ||
1308 | #ifdef CONFIG_TIME_INTERPOLATION | 1355 | #ifdef CONFIG_TIME_INTERPOLATION |
1309 | 1356 | ||
1310 | struct time_interpolator *time_interpolator; | 1357 | struct time_interpolator *time_interpolator __read_mostly; |
1311 | static struct time_interpolator *time_interpolator_list; | 1358 | static struct time_interpolator *time_interpolator_list __read_mostly; |
1312 | static DEFINE_SPINLOCK(time_interpolator_lock); | 1359 | static DEFINE_SPINLOCK(time_interpolator_lock); |
1313 | 1360 | ||
1314 | static inline u64 time_interpolator_get_cycles(unsigned int src) | 1361 | static inline u64 time_interpolator_get_cycles(unsigned int src) |
@@ -1322,10 +1369,10 @@ static inline u64 time_interpolator_get_cycles(unsigned int src) | |||
1322 | return x(); | 1369 | return x(); |
1323 | 1370 | ||
1324 | case TIME_SOURCE_MMIO64 : | 1371 | case TIME_SOURCE_MMIO64 : |
1325 | return readq((void __iomem *) time_interpolator->addr); | 1372 | return readq_relaxed((void __iomem *)time_interpolator->addr); |
1326 | 1373 | ||
1327 | case TIME_SOURCE_MMIO32 : | 1374 | case TIME_SOURCE_MMIO32 : |
1328 | return readl((void __iomem *) time_interpolator->addr); | 1375 | return readl_relaxed((void __iomem *)time_interpolator->addr); |
1329 | 1376 | ||
1330 | default: return get_cycles(); | 1377 | default: return get_cycles(); |
1331 | } | 1378 | } |