diff options
Diffstat (limited to 'kernel/timer.c')
-rw-r--r-- | kernel/timer.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 623f9ea198d8..6811436a031d 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -597,7 +597,6 @@ long time_tolerance = MAXFREQ; /* frequency tolerance (ppm) */ | |||
597 | long time_precision = 1; /* clock precision (us) */ | 597 | long time_precision = 1; /* clock precision (us) */ |
598 | long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ | 598 | long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ |
599 | long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ | 599 | long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ |
600 | static long time_phase; /* phase offset (scaled us) */ | ||
601 | long time_freq = (((NSEC_PER_SEC + HZ/2) % HZ - HZ/2) << SHIFT_USEC) / NSEC_PER_USEC; | 600 | long time_freq = (((NSEC_PER_SEC + HZ/2) % HZ - HZ/2) << SHIFT_USEC) / NSEC_PER_USEC; |
602 | /* frequency offset (scaled ppm)*/ | 601 | /* frequency offset (scaled ppm)*/ |
603 | static long time_adj; /* tick adjust (scaled 1 / HZ) */ | 602 | static long time_adj; /* tick adjust (scaled 1 / HZ) */ |
@@ -747,27 +746,14 @@ static long adjtime_adjustment(void) | |||
747 | } | 746 | } |
748 | 747 | ||
749 | /* in the NTP reference this is called "hardclock()" */ | 748 | /* in the NTP reference this is called "hardclock()" */ |
750 | static void update_wall_time_one_tick(void) | 749 | static void update_ntp_one_tick(void) |
751 | { | 750 | { |
752 | long time_adjust_step, delta_nsec; | 751 | long time_adjust_step; |
753 | 752 | ||
754 | time_adjust_step = adjtime_adjustment(); | 753 | time_adjust_step = adjtime_adjustment(); |
755 | if (time_adjust_step) | 754 | if (time_adjust_step) |
756 | /* Reduce by this step the amount of time left */ | 755 | /* Reduce by this step the amount of time left */ |
757 | time_adjust -= time_adjust_step; | 756 | time_adjust -= time_adjust_step; |
758 | delta_nsec = tick_nsec + time_adjust_step * 1000; | ||
759 | /* | ||
760 | * Advance the phase, once it gets to one microsecond, then | ||
761 | * advance the tick more. | ||
762 | */ | ||
763 | time_phase += time_adj; | ||
764 | if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) { | ||
765 | long ltemp = shift_right(time_phase, (SHIFT_SCALE - 10)); | ||
766 | time_phase -= ltemp << (SHIFT_SCALE - 10); | ||
767 | delta_nsec += ltemp; | ||
768 | } | ||
769 | xtime.tv_nsec += delta_nsec; | ||
770 | time_interpolator_update(delta_nsec); | ||
771 | 757 | ||
772 | /* Changes by adjtime() do not take effect till next tick. */ | 758 | /* Changes by adjtime() do not take effect till next tick. */ |
773 | if (time_next_adjust != 0) { | 759 | if (time_next_adjust != 0) { |
@@ -872,8 +858,13 @@ device_initcall(timekeeping_init_device); | |||
872 | */ | 858 | */ |
873 | static void update_wall_time(void) | 859 | static void update_wall_time(void) |
874 | { | 860 | { |
861 | static s64 remainder_snsecs, error; | ||
862 | s64 snsecs_per_sec; | ||
875 | cycle_t now, offset; | 863 | cycle_t now, offset; |
876 | 864 | ||
865 | snsecs_per_sec = (s64)NSEC_PER_SEC << clock->shift; | ||
866 | remainder_snsecs += (s64)xtime.tv_nsec << clock->shift; | ||
867 | |||
877 | now = read_clocksource(clock); | 868 | now = read_clocksource(clock); |
878 | offset = (now - last_clock_cycle)&clock->mask; | 869 | offset = (now - last_clock_cycle)&clock->mask; |
879 | 870 | ||
@@ -881,17 +872,35 @@ static void update_wall_time(void) | |||
881 | * case of lost or late ticks, it will accumulate correctly. | 872 | * case of lost or late ticks, it will accumulate correctly. |
882 | */ | 873 | */ |
883 | while (offset > clock->interval_cycles) { | 874 | while (offset > clock->interval_cycles) { |
875 | /* get the ntp interval in clock shifted nanoseconds */ | ||
876 | s64 ntp_snsecs = current_tick_length(clock->shift); | ||
877 | |||
884 | /* accumulate one interval */ | 878 | /* accumulate one interval */ |
879 | remainder_snsecs += clock->interval_snsecs; | ||
885 | last_clock_cycle += clock->interval_cycles; | 880 | last_clock_cycle += clock->interval_cycles; |
886 | offset -= clock->interval_cycles; | 881 | offset -= clock->interval_cycles; |
887 | 882 | ||
888 | update_wall_time_one_tick(); | 883 | /* interpolator bits */ |
889 | if (xtime.tv_nsec >= 1000000000) { | 884 | time_interpolator_update(clock->interval_snsecs |
890 | xtime.tv_nsec -= 1000000000; | 885 | >> clock->shift); |
886 | /* increment the NTP state machine */ | ||
887 | update_ntp_one_tick(); | ||
888 | |||
889 | /* accumulate error between NTP and clock interval */ | ||
890 | error += (ntp_snsecs - (s64)clock->interval_snsecs); | ||
891 | |||
892 | /* correct the clock when NTP error is too big */ | ||
893 | remainder_snsecs += make_ntp_adj(clock, offset, &error); | ||
894 | |||
895 | if (remainder_snsecs >= snsecs_per_sec) { | ||
896 | remainder_snsecs -= snsecs_per_sec; | ||
891 | xtime.tv_sec++; | 897 | xtime.tv_sec++; |
892 | second_overflow(); | 898 | second_overflow(); |
893 | } | 899 | } |
894 | } | 900 | } |
901 | /* store full nanoseconds into xtime */ | ||
902 | xtime.tv_nsec = remainder_snsecs >> clock->shift; | ||
903 | remainder_snsecs -= (s64)xtime.tv_nsec << clock->shift; | ||
895 | } | 904 | } |
896 | 905 | ||
897 | /* | 906 | /* |