diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/time.c | 1 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 27 |
2 files changed, 24 insertions, 4 deletions
diff --git a/kernel/time.c b/kernel/time.c index c6324d96009e..804798005d19 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -136,6 +136,7 @@ static inline void warp_clock(void) | |||
136 | write_seqlock_irq(&xtime_lock); | 136 | write_seqlock_irq(&xtime_lock); |
137 | wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; | 137 | wall_to_monotonic.tv_sec -= sys_tz.tz_minuteswest * 60; |
138 | xtime.tv_sec += sys_tz.tz_minuteswest * 60; | 138 | xtime.tv_sec += sys_tz.tz_minuteswest * 60; |
139 | update_xtime_cache(0); | ||
139 | write_sequnlock_irq(&xtime_lock); | 140 | write_sequnlock_irq(&xtime_lock); |
140 | clock_was_set(); | 141 | clock_was_set(); |
141 | } | 142 | } |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index af4135f05825..7faaa32fbf4f 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -165,6 +165,13 @@ 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 | |||
168 | /* must hold xtime_lock */ | 175 | /* must hold xtime_lock */ |
169 | void timekeeping_leap_insert(int leapsecond) | 176 | void timekeeping_leap_insert(int leapsecond) |
170 | { | 177 | { |
@@ -325,6 +332,8 @@ int do_settimeofday(struct timespec *tv) | |||
325 | 332 | ||
326 | xtime = *tv; | 333 | xtime = *tv; |
327 | 334 | ||
335 | update_xtime_cache(0); | ||
336 | |||
328 | timekeeper.ntp_error = 0; | 337 | timekeeper.ntp_error = 0; |
329 | ntp_clear(); | 338 | ntp_clear(); |
330 | 339 | ||
@@ -550,6 +559,7 @@ void __init timekeeping_init(void) | |||
550 | } | 559 | } |
551 | set_normalized_timespec(&wall_to_monotonic, | 560 | set_normalized_timespec(&wall_to_monotonic, |
552 | -boot.tv_sec, -boot.tv_nsec); | 561 | -boot.tv_sec, -boot.tv_nsec); |
562 | update_xtime_cache(0); | ||
553 | total_sleep_time.tv_sec = 0; | 563 | total_sleep_time.tv_sec = 0; |
554 | total_sleep_time.tv_nsec = 0; | 564 | total_sleep_time.tv_nsec = 0; |
555 | write_sequnlock_irqrestore(&xtime_lock, flags); | 565 | write_sequnlock_irqrestore(&xtime_lock, flags); |
@@ -583,6 +593,7 @@ static int timekeeping_resume(struct sys_device *dev) | |||
583 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); | 593 | wall_to_monotonic = timespec_sub(wall_to_monotonic, ts); |
584 | total_sleep_time = timespec_add_safe(total_sleep_time, ts); | 594 | total_sleep_time = timespec_add_safe(total_sleep_time, ts); |
585 | } | 595 | } |
596 | update_xtime_cache(0); | ||
586 | /* re-base the last cycle value */ | 597 | /* re-base the last cycle value */ |
587 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); | 598 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); |
588 | timekeeper.ntp_error = 0; | 599 | timekeeper.ntp_error = 0; |
@@ -722,6 +733,7 @@ static void timekeeping_adjust(s64 offset) | |||
722 | timekeeper.ntp_error_shift; | 733 | timekeeper.ntp_error_shift; |
723 | } | 734 | } |
724 | 735 | ||
736 | |||
725 | /** | 737 | /** |
726 | * logarithmic_accumulation - shifted accumulation of cycles | 738 | * logarithmic_accumulation - shifted accumulation of cycles |
727 | * | 739 | * |
@@ -765,6 +777,7 @@ static cycle_t logarithmic_accumulation(cycle_t offset, int shift) | |||
765 | return offset; | 777 | return offset; |
766 | } | 778 | } |
767 | 779 | ||
780 | |||
768 | /** | 781 | /** |
769 | * update_wall_time - Uses the current clocksource to increment the wall time | 782 | * update_wall_time - Uses the current clocksource to increment the wall time |
770 | * | 783 | * |
@@ -774,6 +787,7 @@ void update_wall_time(void) | |||
774 | { | 787 | { |
775 | struct clocksource *clock; | 788 | struct clocksource *clock; |
776 | cycle_t offset; | 789 | cycle_t offset; |
790 | u64 nsecs; | ||
777 | int shift = 0, maxshift; | 791 | int shift = 0, maxshift; |
778 | 792 | ||
779 | /* Make sure we're fully resumed: */ | 793 | /* Make sure we're fully resumed: */ |
@@ -839,6 +853,9 @@ void update_wall_time(void) | |||
839 | timekeeper.ntp_error += timekeeper.xtime_nsec << | 853 | timekeeper.ntp_error += timekeeper.xtime_nsec << |
840 | timekeeper.ntp_error_shift; | 854 | timekeeper.ntp_error_shift; |
841 | 855 | ||
856 | nsecs = clocksource_cyc2ns(offset, timekeeper.mult, timekeeper.shift); | ||
857 | update_xtime_cache(nsecs); | ||
858 | |||
842 | /* check to see if there is a new clocksource to use */ | 859 | /* check to see if there is a new clocksource to use */ |
843 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); | 860 | update_vsyscall(&xtime, timekeeper.clock, timekeeper.mult); |
844 | } | 861 | } |
@@ -875,13 +892,13 @@ void monotonic_to_bootbased(struct timespec *ts) | |||
875 | 892 | ||
876 | unsigned long get_seconds(void) | 893 | unsigned long get_seconds(void) |
877 | { | 894 | { |
878 | return xtime.tv_sec; | 895 | return xtime_cache.tv_sec; |
879 | } | 896 | } |
880 | EXPORT_SYMBOL(get_seconds); | 897 | EXPORT_SYMBOL(get_seconds); |
881 | 898 | ||
882 | struct timespec __current_kernel_time(void) | 899 | struct timespec __current_kernel_time(void) |
883 | { | 900 | { |
884 | return xtime; | 901 | return xtime_cache; |
885 | } | 902 | } |
886 | 903 | ||
887 | struct timespec current_kernel_time(void) | 904 | struct timespec current_kernel_time(void) |
@@ -891,7 +908,8 @@ struct timespec current_kernel_time(void) | |||
891 | 908 | ||
892 | do { | 909 | do { |
893 | seq = read_seqbegin(&xtime_lock); | 910 | seq = read_seqbegin(&xtime_lock); |
894 | now = xtime; | 911 | |
912 | now = xtime_cache; | ||
895 | } while (read_seqretry(&xtime_lock, seq)); | 913 | } while (read_seqretry(&xtime_lock, seq)); |
896 | 914 | ||
897 | return now; | 915 | return now; |
@@ -905,7 +923,8 @@ struct timespec get_monotonic_coarse(void) | |||
905 | 923 | ||
906 | do { | 924 | do { |
907 | seq = read_seqbegin(&xtime_lock); | 925 | seq = read_seqbegin(&xtime_lock); |
908 | now = xtime; | 926 | |
927 | now = xtime_cache; | ||
909 | mono = wall_to_monotonic; | 928 | mono = wall_to_monotonic; |
910 | } while (read_seqretry(&xtime_lock, seq)); | 929 | } while (read_seqretry(&xtime_lock, seq)); |
911 | 930 | ||