Skip to content

Commit 78b98e3

Browse files
mlichvarIngo Molnar
authored andcommitted
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>
1 parent c2cda2a commit 78b98e3

File tree

2 files changed

+49
-91
lines changed

2 files changed

+49
-91
lines changed

include/linux/timekeeper_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ struct timekeeper {
117117
s64 ntp_error;
118118
u32 ntp_error_shift;
119119
u32 ntp_err_mult;
120+
/* Flag used to avoid updating NTP twice with same second */
121+
u32 skip_second_overflow;
120122
#ifdef CONFIG_DEBUG_TIMEKEEPING
121123
long last_warning;
122124
/*

kernel/time/timekeeping.c

Lines changed: 47 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
332332
tk->tkr_mono.mult = clock->mult;
333333
tk->tkr_raw.mult = clock->mult;
334334
tk->ntp_err_mult = 0;
335+
tk->skip_second_overflow = 0;
335336
}
336337

337338
/* Timekeeper helper functions. */
@@ -1799,20 +1800,19 @@ device_initcall(timekeeping_init_ops);
17991800
*/
18001801
static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
18011802
s64 offset,
1802-
bool negative,
1803-
int adj_scale)
1803+
s32 mult_adj)
18041804
{
18051805
s64 interval = tk->cycle_interval;
1806-
s32 mult_adj = 1;
18071806

1808-
if (negative) {
1809-
mult_adj = -mult_adj;
1807+
if (mult_adj == 0) {
1808+
return;
1809+
} else if (mult_adj == -1) {
18101810
interval = -interval;
1811-
offset = -offset;
1811+
offset = -offset;
1812+
} else if (mult_adj != 1) {
1813+
interval *= mult_adj;
1814+
offset *= mult_adj;
18121815
}
1813-
mult_adj <<= adj_scale;
1814-
interval <<= adj_scale;
1815-
offset <<= adj_scale;
18161816

18171817
/*
18181818
* So the following can be confusing.
@@ -1873,85 +1873,35 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
18731873
}
18741874

18751875
/*
1876-
* Calculate the multiplier adjustment needed to match the frequency
1877-
* specified by NTP
1876+
* Adjust the timekeeper's multiplier to the correct frequency
1877+
* and also to reduce the accumulated error value.
18781878
*/
1879-
static __always_inline void timekeeping_freqadjust(struct timekeeper *tk,
1880-
s64 offset)
1879+
static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
18811880
{
1882-
s64 interval = tk->cycle_interval;
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);
1881+
u32 mult;
19071882

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;
19131883
/*
1914-
* Sort out the magnitude of the correction, but
1915-
* avoid making so large a correction that we go
1916-
* over the max adjustment.
1884+
* Determine the multiplier from the current NTP tick length.
1885+
* Avoid expensive division when the tick length doesn't change.
19171886
*/
1918-
adj_scale = 0;
1919-
tick_error = abs(tick_error);
1920-
while (tick_error > interval) {
1921-
u32 adj = 1 << (adj_scale + 1);
1922-
1923-
/* Check if adjustment gets us within 1 unit from the max */
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;
1887+
if (likely(tk->ntp_tick == ntp_tick_length())) {
1888+
mult = tk->tkr_mono.mult - tk->ntp_err_mult;
1889+
} else {
1890+
tk->ntp_tick = ntp_tick_length();
1891+
mult = div64_u64((tk->ntp_tick >> tk->ntp_error_shift) -
1892+
tk->xtime_remainder, tk->cycle_interval);
19311893
}
19321894

1933-
/* scale the corrections */
1934-
timekeeping_apply_adjustment(tk, offset, negative, adj_scale);
1935-
}
1895+
/*
1896+
* If the clock is behind the NTP time, increase the multiplier by 1
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;
19361903

1937-
/*
1938-
* Adjust the timekeeper's multiplier to the correct frequency
1939-
* and also to reduce the accumulated error value.
1940-
*/
1941-
static 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-
}
1904+
timekeeping_apply_adjustment(tk, offset, mult - tk->tkr_mono.mult);
19551905

19561906
if (unlikely(tk->tkr_mono.clock->maxadj &&
19571907
(abs(tk->tkr_mono.mult - tk->tkr_mono.clock->mult)
@@ -1968,18 +1918,15 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
19681918
* in the code above, its possible the required corrective factor to
19691919
* xtime_nsec could cause it to underflow.
19701920
*
1971-
* Now, since we already accumulated the second, cannot simply roll
1972-
* the accumulated second back, since the NTP subsystem has been
1973-
* notified via second_overflow. So instead we push xtime_nsec forward
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.
1921+
* Now, since we have already accumulated the second and the NTP
1922+
* subsystem has been notified via second_overflow(), we need to skip
1923+
* the next update.
19781924
*/
19791925
if (unlikely((s64)tk->tkr_mono.xtime_nsec < 0)) {
1980-
s64 neg = -(s64)tk->tkr_mono.xtime_nsec;
1981-
tk->tkr_mono.xtime_nsec = 0;
1982-
tk->ntp_error += neg << tk->ntp_error_shift;
1926+
tk->tkr_mono.xtime_nsec += (u64)NSEC_PER_SEC <<
1927+
tk->tkr_mono.shift;
1928+
tk->xtime_sec--;
1929+
tk->skip_second_overflow = 1;
19831930
}
19841931
}
19851932

@@ -2002,6 +1949,15 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
20021949
tk->tkr_mono.xtime_nsec -= nsecps;
20031950
tk->xtime_sec++;
20041951

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+
20051961
/* Figure out if its a leap sec and apply if needed */
20061962
leap = second_overflow(tk->xtime_sec);
20071963
if (unlikely(leap)) {
@@ -2118,7 +2074,7 @@ void update_wall_time(void)
21182074
shift--;
21192075
}
21202076

2121-
/* correct the clock when NTP error is too big */
2077+
/* Adjust the multiplier to correct NTP error */
21222078
timekeeping_adjust(tk, offset);
21232079

21242080
/*

0 commit comments

Comments
 (0)