diff options
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r-- | kernel/time/timekeeping.c | 119 |
1 files changed, 73 insertions, 46 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index c3a4e2907eaa..d1aebd73b191 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -165,13 +165,6 @@ struct timespec raw_time; | |||
165 | /* flag for if timekeeping is suspended */ | 165 | /* flag for if timekeeping is suspended */ |
166 | int __read_mostly timekeeping_suspended; | 166 | int __read_mostly timekeeping_suspended; |
167 | 167 | ||
168 | static struct timespec xtime_cache __attribute__ ((aligned (16))); | ||
169 | void update_xtime_cache(u64 nsec) | ||
170 | { | ||
171 | xtime_cache = xtime; | ||
172 | timespec_add_ns(&xtime_cache, nsec); | ||
173 | } | ||
174 | |||
175 | /* must hold xtime_lock */ | 168 | /* must hold xtime_lock */ |
176 | void timekeeping_leap_insert(int leapsecond) | 169 | void timekeeping_leap_insert(int leapsecond) |
177 | { | 170 | { |
@@ -332,8 +325,6 @@ int do_settimeofday(struct timespec *tv) | |||
332 | 325 | ||
333 | xtime = *tv; | 326 | xtime = *tv; |
334 | 327 | ||
335 | update_xtime_cache(0); | ||
336 | |||
337 | timekeeper.ntp_error = 0; | 328 | timekeeper.ntp_error = 0; |
338 | ntp_clear(); | 329 | ntp_clear(); |
339 | 330 | ||
@@ -488,6 +479,17 @@ int timekeeping_valid_for_hres(void) | |||
488 | } | 479 | } |
489 | 480 | ||
490 | /** | 481 | /** |
482 | * timekeeping_max_deferment - Returns max time the clocksource can be deferred | ||
483 | * | ||
484 | * Caller must observe xtime_lock via read_seqbegin/read_seqretry to | ||
485 | * ensure that the clocksource does not change! | ||
486 | */ | ||
487 | u64 timekeeping_max_deferment(void) | ||
488 | { | ||
489 | return timekeeper.clock->max_idle_ns; | ||
490 | } | ||
491 | |||
492 | /** | ||
491 | * read_persistent_clock - Return time from the persistent clock. | 493 | * read_persistent_clock - Return time from the persistent clock. |
492 | * | 494 | * |
493 | * Weak dummy function for arches that do not yet support it. | 495 | * Weak dummy function for arches that do not yet support it. |
@@ -548,7 +550,6 @@ void __init timekeeping_init(void) | |||
548 | } | 550 | } |
549 | set_normalized_timespec(&wall_to_monotonic, | 551 | set_normalized_timespec(&wall_to_monotonic, |
550 | -boot.tv_sec, -boot.tv_nsec); | 552 | -boot.tv_sec, -boot.tv_nsec); |
551 | update_xtime_cache(0); | ||
552 | total_sleep_time.tv_sec = 0; | 553 | total_sleep_time.tv_sec = 0; |
553 | total_sleep_time.tv_nsec = 0; | 554 | total_sleep_time.tv_nsec = 0; |
554 | write_sequnlock_irqrestore(&xtime_lock, flags); | 555 | write_sequnlock_irqrestore(&xtime_lock, flags); |
@@ -582,7 +583,6 @@ static int timekeeping_resume(struct sys_device *dev) | |||
582 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); | 583 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); |
583 | total_sleep_time = timespec_add_safe(total_sleep_time, ts); | 584 | total_sleep_time = timespec_add_safe(total_sleep_time, ts); |
584 | } | 585 | } |
585 | update_xtime_cache(0); | ||
586 | /* re-base the last cycle value */ | 586 | /* re-base the last cycle value */ |
587 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); | 587 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); |
588 | timekeeper.ntp_error = 0; | 588 | timekeeper.ntp_error = 0; |
@@ -723,6 +723,49 @@ static void timekeeping_adjust(s64 offset) | |||
723 | } | 723 | } |
724 | 724 | ||
725 | /** | 725 | /** |
726 | * logarithmic_accumulation - shifted accumulation of cycles | ||
727 | * | ||
728 | * This functions accumulates a shifted interval of cycles into | ||
729 | * into a shifted interval nanoseconds. Allows for O(log) accumulation | ||
730 | * loop. | ||
731 | * | ||
732 | * Returns the unconsumed cycles. | ||
733 | */ | ||
734 | static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | ||
735 | { | ||
736 | u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift; | ||
737 | |||
738 | /* If the offset is smaller then a shifted interval, do nothing */ | ||
739 | if (offset < timekeeper.cycle_interval<<shift) | ||
740 | return offset; | ||
741 | |||
742 | /* Accumulate one shifted interval */ | ||
743 | offset -= timekeeper.cycle_interval << shift; | ||
744 | timekeeper.clock->cycle_last += timekeeper.cycle_interval << shift; | ||
745 | |||
746 | timekeeper.xtime_nsec += timekeeper.xtime_interval << shift; | ||
747 | while (timekeeper.xtime_nsec >= nsecps) { | ||
748 | timekeeper.xtime_nsec -= nsecps; | ||
749 | xtime.tv_sec++; | ||
750 | second_overflow(); | ||
751 | } | ||
752 | |||
753 | /* Accumulate into raw time */ | ||
754 | raw_time.tv_nsec += timekeeper.raw_interval << shift;; | ||
755 | while (raw_time.tv_nsec >= NSEC_PER_SEC) { | ||
756 | raw_time.tv_nsec -= NSEC_PER_SEC; | ||
757 | raw_time.tv_sec++; | ||
758 | } | ||
759 | |||
760 | /* Accumulate error between NTP and clock interval */ | ||
761 | timekeeper.ntp_error += tick_length << shift; | ||
762 | timekeeper.ntp_error -= timekeeper.xtime_interval << | ||
763 | (timekeeper.ntp_error_shift + shift); | ||
764 | |||
765 | return offset; | ||
766 | } | ||
767 | |||
768 | /** | ||
726 | * update_wall_time - Uses the current clocksource to increment the wall time | 769 | * update_wall_time - Uses the current clocksource to increment the wall time |
727 | * | 770 | * |
728 | * Called from the timer interrupt, must hold a write on xtime_lock. | 771 | * Called from the timer interrupt, must hold a write on xtime_lock. |
@@ -731,7 +774,7 @@ void update_wall_time(void) | |||
731 | { | 774 | { |
732 | struct clocksource *clock; | 775 | struct clocksource *clock; |
733 | cycle_t offset; | 776 | cycle_t offset; |
734 | u64 nsecs; | 777 | int shift = 0, maxshift; |
735 | 778 | ||
736 | /* Make sure we're fully resumed: */ | 779 | /* Make sure we're fully resumed: */ |
737 | if (unlikely(timekeeping_suspended)) | 780 | if (unlikely(timekeeping_suspended)) |
@@ -745,33 +788,22 @@ void update_wall_time(void) | |||
745 | #endif | 788 | #endif |
746 | timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift; | 789 | timekeeper.xtime_nsec = (s64)xtime.tv_nsec << timekeeper.shift; |
747 | 790 | ||
748 | /* normally this loop will run just once, however in the | 791 | /* |
749 | * case of lost or late ticks, it will accumulate correctly. | 792 | * With NO_HZ we may have to accumulate many cycle_intervals |
793 | * (think "ticks") worth of time at once. To do this efficiently, | ||
794 | * we calculate the largest doubling multiple of cycle_intervals | ||
795 | * that is smaller then the offset. We then accumulate that | ||
796 | * chunk in one go, and then try to consume the next smaller | ||
797 | * doubled multiple. | ||
750 | */ | 798 | */ |
799 | shift = ilog2(offset) - ilog2(timekeeper.cycle_interval); | ||
800 | shift = max(0, shift); | ||
801 | /* Bound shift to one less then what overflows tick_length */ | ||
802 | maxshift = (8*sizeof(tick_length) - (ilog2(tick_length)+1)) - 1; | ||
803 | shift = min(shift, maxshift); | ||
751 | while (offset >= timekeeper.cycle_interval) { | 804 | while (offset >= timekeeper.cycle_interval) { |
752 | u64 nsecps = (u64)NSEC_PER_SEC << timekeeper.shift; | 805 | offset = logarithmic_accumulation(offset, shift); |
753 | 806 | shift--; | |
754 | /* accumulate one interval */ | ||
755 | offset -= timekeeper.cycle_interval; | ||
756 | clock->cycle_last += timekeeper.cycle_interval; | ||
757 | |||
758 | timekeeper.xtime_nsec += timekeeper.xtime_interval; | ||
759 | if (timekeeper.xtime_nsec >= nsecps) { | ||
760 | timekeeper.xtime_nsec -= nsecps; | ||
761 | xtime.tv_sec++; | ||
762 | second_overflow(); | ||
763 | } | ||
764 | |||
765 | raw_time.tv_nsec += timekeeper.raw_interval; | ||
766 | if (raw_time.tv_nsec >= NSEC_PER_SEC) { | ||
767 | raw_time.tv_nsec -= NSEC_PER_SEC; | ||
768 | raw_time.tv_sec++; | ||
769 | } | ||
770 | |||
771 | /* accumulate error between NTP and clock interval */ | ||
772 | timekeeper.ntp_error += tick_length; | ||
773 | timekeeper.ntp_error -= timekeeper.xtime_interval << | ||
774 | timekeeper.ntp_error_shift; | ||
775 | } | 807 | } |
776 | 808 | ||
777 | /* correct the clock when NTP error is too big */ | 809 | /* correct the clock when NTP error is too big */ |
@@ -807,9 +839,6 @@ void update_wall_time(void) | |||
807 | timekeeper.ntp_error += timekeeper.xtime_nsec << | 839 | timekeeper.ntp_error += timekeeper.xtime_nsec << |
808 | timekeeper.ntp_error_shift; | 840 | timekeeper.ntp_error_shift; |
809 | 841 | ||
810 | nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift); | ||
811 | update_xtime_cache(nsecs); | ||
812 | |||
813 | /* check to see if there is a new clocksource to use */ | 842 | /* check to see if there is a new clocksource to use */ |
814 | update_vsyscall(&xtime, timekeeper.clock); | 843 | update_vsyscall(&xtime, timekeeper.clock); |
815 | } | 844 | } |
@@ -846,13 +875,13 @@ void monotonic_to_bootbased(struct timespec *ts) | |||
846 | 875 | ||
847 | unsigned long get_seconds(void) | 876 | unsigned long get_seconds(void) |
848 | { | 877 | { |
849 | return xtime_cache.tv_sec; | 878 | return xtime.tv_sec; |
850 | } | 879 | } |
851 | EXPORT_SYMBOL(get_seconds); | 880 | EXPORT_SYMBOL(get_seconds); |
852 | 881 | ||
853 | struct timespec __current_kernel_time(void) | 882 | struct timespec __current_kernel_time(void) |
854 | { | 883 | { |
855 | return xtime_cache; | 884 | return xtime; |
856 | } | 885 | } |
857 | 886 | ||
858 | struct timespec current_kernel_time(void) | 887 | struct timespec current_kernel_time(void) |
@@ -862,8 +891,7 @@ struct timespec current_kernel_time(void) | |||
862 | 891 | ||
863 | do { | 892 | do { |
864 | seq = read_seqbegin(&xtime_lock); | 893 | seq = read_seqbegin(&xtime_lock); |
865 | 894 | now = xtime; | |
866 | now = xtime_cache; | ||
867 | } while (read_seqretry(&xtime_lock, seq)); | 895 | } while (read_seqretry(&xtime_lock, seq)); |
868 | 896 | ||
869 | return now; | 897 | return now; |
@@ -877,8 +905,7 @@ struct timespec get_monotonic_coarse(void) | |||
877 | 905 | ||
878 | do { | 906 | do { |
879 | seq = read_seqbegin(&xtime_lock); | 907 | seq = read_seqbegin(&xtime_lock); |
880 | 908 | now = xtime; | |
881 | now = xtime_cache; | ||
882 | mono = wall_to_monotonic; | 909 | mono = wall_to_monotonic; |
883 | } while (read_seqretry(&xtime_lock, seq)); | 910 | } while (read_seqretry(&xtime_lock, seq)); |
884 | 911 | ||