aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiroslav Lichvar <mlichvar@redhat.com>2018-03-09 13:42:48 -0500
committerIngo Molnar <mingo@kernel.org>2018-03-10 03:12:41 -0500
commit78b98e3c5a66d569a53b8f57b6a698f912794a43 (patch)
treed4306491e8e4ce50d1fd8decfac0e5c9e14fc8cd
parentc2cda2a5bda9f1369c9d1ab54a20571c13cf2743 (diff)
timekeeping/ntp: Determine the multiplier directly from NTP tick length
When the length of the NTP tick changes significantly, e.g. when an NTP/PTP application is correcting the initial offset of the clock, a large value may accumulate in the NTP error before the multiplier converges to the correct value. It may then take a very long time (hours or even days) before the error is corrected. This causes the clock to have an unstable frequency offset, which has a negative impact on the stability of synchronization with precise time sources (e.g. NTP/PTP using hardware timestamping or the PTP KVM clock). Use division to determine the correct multiplier directly from the NTP tick length and replace the iterative approach. This removes the last major source of the NTP error. The only remaining source is now limited resolution of the multiplier, which is corrected by adding 1 to the multiplier when the system clock is behind the NTP time. Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com> Signed-off-by: John Stultz <john.stultz@linaro.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Prarit Bhargava <prarit@redhat.com> Cc: Richard Cochran <richardcochran@gmail.com> Cc: Stephen Boyd <stephen.boyd@linaro.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/1520620971-9567-3-git-send-email-john.stultz@linaro.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--include/linux/timekeeper_internal.h2
-rw-r--r--kernel/time/timekeeping.c138
2 files changed, 49 insertions, 91 deletions
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index d315c3d6725c..7acb953298a7 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -117,6 +117,8 @@ struct timekeeper {
117 s64 ntp_error; 117 s64 ntp_error;
118 u32 ntp_error_shift; 118 u32 ntp_error_shift;
119 u32 ntp_err_mult; 119 u32 ntp_err_mult;
120 /* Flag used to avoid updating NTP twice with same second */
121 u32 skip_second_overflow;
120#ifdef CONFIG_DEBUG_TIMEKEEPING 122#ifdef CONFIG_DEBUG_TIMEKEEPING
121 long last_warning; 123 long last_warning;
122 /* 124 /*
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c1a0ac17336e..e11760121cb2 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -332,6 +332,7 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
332 tk->tkr_mono.mult = clock->mult; 332 tk->tkr_mono.mult = clock->mult;
333 tk->tkr_raw.mult = clock->mult; 333 tk->tkr_raw.mult = clock->mult;
334 tk->ntp_err_mult = 0; 334 tk->ntp_err_mult = 0;
335 tk->skip_second_overflow = 0;
335} 336}
336 337
337/* Timekeeper helper functions. */ 338/* Timekeeper helper functions. */
@@ -1799,20 +1800,19 @@ device_initcall(timekeeping_init_ops);
1799 */ 1800 */
1800static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk, 1801static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
1801 s64 offset, 1802 s64 offset,
1802 bool negative, 1803 s32 mult_adj)
1803 int adj_scale)
1804{ 1804{
1805 s64 interval = tk->cycle_interval; 1805 s64 interval = tk->cycle_interval;
1806 s32 mult_adj = 1;
1807 1806
1808 if (negative) { 1807 if (mult_adj == 0) {
1809 mult_adj = -mult_adj; 1808 return;
1809 } else if (mult_adj == -1) {
1810 interval = -interval; 1810 interval = -interval;
1811 offset = -offset; 1811 offset = -offset;
1812 } else if (mult_adj != 1) {
1813 interval *= mult_adj;
1814 offset *= mult_adj;
1812 } 1815 }
1813 mult_adj <<= adj_scale;
1814 interval <<= adj_scale;
1815 offset <<= adj_scale;
1816 1816
1817 /* 1817 /*
1818 * So the following can be confusing. 1818 * So the following can be confusing.
@@ -1873,85 +1873,35 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
1873} 1873}
1874 1874
1875/* 1875/*
1876 * Calculate the multiplier adjustment needed to match the frequency 1876 * Adjust the timekeeper's multiplier to the correct frequency
1877 * specified by NTP 1877 * and also to reduce the accumulated error value.
1878 */ 1878 */
1879static __always_inline void timekeeping_freqadjust(struct timekeeper *tk, 1879static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
1880 s64 offset)
1881{ 1880{
1882 s64 interval = tk->cycle_interval; 1881 u32 mult;
1883 s64 xinterval = tk->xtime_interval;
1884 u32 base = tk->tkr_mono.clock->mult;
1885 u32 max = tk->tkr_mono.clock->maxadj;
1886 u32 cur_adj = tk->tkr_mono.mult;
1887 s64 tick_error;
1888 bool negative;
1889 u32 adj_scale;
1890
1891 /* Remove any current error adj from freq calculation */
1892 if (tk->ntp_err_mult)
1893 xinterval -= tk->cycle_interval;
1894
1895 tk->ntp_tick = ntp_tick_length();
1896
1897 /* Calculate current error per tick */
1898 tick_error = ntp_tick_length() >> tk->ntp_error_shift;
1899 tick_error -= (xinterval + tk->xtime_remainder);
1900
1901 /* Don't worry about correcting it if its small */
1902 if (likely((tick_error >= 0) && (tick_error <= interval)))
1903 return;
1904
1905 /* preserve the direction of correction */
1906 negative = (tick_error < 0);
1907 1882
1908 /* If any adjustment would pass the max, just return */
1909 if (negative && (cur_adj - 1) <= (base - max))
1910 return;
1911 if (!negative && (cur_adj + 1) >= (base + max))
1912 return;
1913 /* 1883 /*
1914 * Sort out the magnitude of the correction, but 1884 * Determine the multiplier from the current NTP tick length.
1915 * avoid making so large a correction that we go 1885 * Avoid expensive division when the tick length doesn't change.
1916 * over the max adjustment.
1917 */ 1886 */
1918 adj_scale = 0; 1887 if (likely(tk->ntp_tick == ntp_tick_length())) {
1919 tick_error = abs(tick_error); 1888 mult = tk->tkr_mono.mult - tk->ntp_err_mult;
1920 while (tick_error > interval) { 1889 } else {
1921 u32 adj = 1 << (adj_scale + 1); 1890 tk->ntp_tick = ntp_tick_length();
1922 1891 mult = div64_u64((tk->ntp_tick >> tk->ntp_error_shift) -
1923 /* Check if adjustment gets us within 1 unit from the max */ 1892 tk->xtime_remainder, tk->cycle_interval);
1924 if (negative && (cur_adj - adj) <= (base - max))
1925 break;
1926 if (!negative && (cur_adj + adj) >= (base + max))
1927 break;
1928
1929 adj_scale++;
1930 tick_error >>= 1;
1931 } 1893 }
1932 1894
1933 /* scale the corrections */ 1895 /*
1934 timekeeping_apply_adjustment(tk, offset, negative, adj_scale); 1896 * If the clock is behind the NTP time, increase the multiplier by 1
1935} 1897 * to catch up with it. If it's ahead and there was a remainder in the
1898 * tick division, the clock will slow down. Otherwise it will stay
1899 * ahead until the tick length changes to a non-divisible value.
1900 */
1901 tk->ntp_err_mult = tk->ntp_error > 0 ? 1 : 0;
1902 mult += tk->ntp_err_mult;
1936 1903
1937/* 1904 timekeeping_apply_adjustment(tk, offset, mult - tk->tkr_mono.mult);
1938 * Adjust the timekeeper's multiplier to the correct frequency
1939 * and also to reduce the accumulated error value.
1940 */
1941static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
1942{
1943 /* Correct for the current frequency error */
1944 timekeeping_freqadjust(tk, offset);
1945
1946 /* Next make a small adjustment to fix any cumulative error */
1947 if (!tk->ntp_err_mult && (tk->ntp_error > 0)) {
1948 tk->ntp_err_mult = 1;
1949 timekeeping_apply_adjustment(tk, offset, 0, 0);
1950 } else if (tk->ntp_err_mult && (tk->ntp_error <= 0)) {
1951 /* Undo any existing error adjustment */
1952 timekeeping_apply_adjustment(tk, offset, 1, 0);
1953 tk->ntp_err_mult = 0;
1954 }
1955 1905
1956 if (unlikely(tk->tkr_mono.clock->maxadj && 1906 if (unlikely(tk->tkr_mono.clock->maxadj &&
1957 (abs(tk->tkr_mono.mult - tk->tkr_mono.clock->mult) 1907 (abs(tk->tkr_mono.mult - tk->tkr_mono.clock->mult)
@@ -1968,18 +1918,15 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
1968 * in the code above, its possible the required corrective factor to 1918 * in the code above, its possible the required corrective factor to
1969 * xtime_nsec could cause it to underflow. 1919 * xtime_nsec could cause it to underflow.
1970 * 1920 *
1971 * Now, since we already accumulated the second, cannot simply roll 1921 * Now, since we have already accumulated the second and the NTP
1972 * the accumulated second back, since the NTP subsystem has been 1922 * subsystem has been notified via second_overflow(), we need to skip
1973 * notified via second_overflow. So instead we push xtime_nsec forward 1923 * the next update.
1974 * by the amount we underflowed, and add that amount into the error.
1975 *
1976 * We'll correct this error next time through this function, when
1977 * xtime_nsec is not as small.
1978 */ 1924 */
1979 if (unlikely((s64)tk->tkr_mono.xtime_nsec < 0)) { 1925 if (unlikely((s64)tk->tkr_mono.xtime_nsec < 0)) {
1980 s64 neg = -(s64)tk->tkr_mono.xtime_nsec; 1926 tk->tkr_mono.xtime_nsec += (u64)NSEC_PER_SEC <<
1981 tk->tkr_mono.xtime_nsec = 0; 1927 tk->tkr_mono.shift;
1982 tk->ntp_error += neg << tk->ntp_error_shift; 1928 tk->xtime_sec--;
1929 tk->skip_second_overflow = 1;
1983 } 1930 }
1984} 1931}
1985 1932
@@ -2002,6 +1949,15 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
2002 tk->tkr_mono.xtime_nsec -= nsecps; 1949 tk->tkr_mono.xtime_nsec -= nsecps;
2003 tk->xtime_sec++; 1950 tk->xtime_sec++;
2004 1951
1952 /*
1953 * Skip NTP update if this second was accumulated before,
1954 * i.e. xtime_nsec underflowed in timekeeping_adjust()
1955 */
1956 if (unlikely(tk->skip_second_overflow)) {
1957 tk->skip_second_overflow = 0;
1958 continue;
1959 }
1960
2005 /* Figure out if its a leap sec and apply if needed */ 1961 /* Figure out if its a leap sec and apply if needed */
2006 leap = second_overflow(tk->xtime_sec); 1962 leap = second_overflow(tk->xtime_sec);
2007 if (unlikely(leap)) { 1963 if (unlikely(leap)) {
@@ -2118,7 +2074,7 @@ void update_wall_time(void)
2118 shift--; 2074 shift--;
2119 } 2075 }
2120 2076
2121 /* correct the clock when NTP error is too big */ 2077 /* Adjust the multiplier to correct NTP error */
2122 timekeeping_adjust(tk, offset); 2078 timekeeping_adjust(tk, offset);
2123 2079
2124 /* 2080 /*