// SPDX-License-Identifier: GPL-2.0/* * NTP state machine interfaces and logic. * * This code was mainly moved from kernel/timer.c and kernel/time.c * Please see those files for relevant copyright info and historical * changelogs. */#include <linux/capability.h>#include <linux/clocksource.h>#include <linux/workqueue.h>#include <linux/hrtimer.h>#include <linux/jiffies.h>#include <linux/math64.h>#include <linux/timex.h>#include <linux/time.h>#include <linux/mm.h>#include <linux/module.h>#include <linux/rtc.h>#include <linux/audit.h>#include <linux/timekeeper_internal.h> #include "ntp_internal.h"#include "timekeeping_internal.h" /** * struct ntp_data - Structure holding all NTP related state * @tick_usec: USER_HZ period in microseconds * @tick_length: Tick length in ns << NTP_SCALE_SHIFT * @time_state: State of the clock synchronization * @time_status: Clock status bits * @time_offset: Time adjustment in nanoseconds * @skew_delta: Per-tick phase slew rate for the coming second, in * @time_offset units (shifted-ns / HZ). Set by * second_overflow(). * @time_constant: PLL time constant * @time_maxerror: Maximum error in microseconds holding the NTP sync distance * (NTP dispersion + delay / 2) * @time_esterror: Estimated error in microseconds holding NTP dispersion * @time_freq: Frequency offset scaled nsecs/secs * @time_reftime: Time at last adjustment in seconds * @time_adjust: Adjustment value * @time_adjust_frac: Sub-microsecond remainder of @time_adjust being * delivered, in ns << NTP_SCALE_SHIFT (not divided by HZ). * @ntp_tick_adj: Constant boot-param configurable NTP tick adjustment (upscaled) * @cs_tick_adj: Fixed per-second adjustment compensating for the difference * between the nominal NTP interval and the real time taken * by the clocksource's integer @cycle_interval (upscaled). * Set by the timekeeping core via ntp_clear(). * @ntp_next_leap_sec: Second value of the next pending leapsecond, or TIME64_MAX if no leap * * @pps_valid: PPS signal watchdog counter * @pps_tf: PPS phase median filter * @pps_jitter: PPS current jitter in nanoseconds * @pps_fbase: PPS beginning of the last freq interval * @pps_shift: PPS current interval duration in seconds (shift value) * @pps_intcnt: PPS interval counter * @pps_freq: PPS frequency offset in scaled ns/s * @pps_stabil: PPS current stability in scaled ns/s * @pps_calcnt: PPS monitor: calibration intervals * @pps_jitcnt: PPS monitor: jitter limit exceeded * @pps_stbcnt: PPS monitor: stability limit exceeded * @pps_errcnt: PPS monitor: calibration errors * * Protected by the timekeeping locks. */struct ntp_data { unsigned long tick_usec; u64 tick_length; int time_state; int time_status; s64 time_offset; s64 skew_delta; long time_constant; long time_maxerror; long time_esterror; s64 time_freq; time64_t time_reftime; long time_adjust; s64 time_adjust_frac; s64 ntp_tick_adj; s64 cs_tick_adj; time64_t ntp_next_leap_sec;#ifdef CONFIG_NTP_PPS int pps_valid; long pps_tf[3]; long pps_jitter; struct timespec64 pps_fbase; int pps_shift; int pps_intcnt; s64 pps_freq; long pps_stabil; long pps_calcnt; long pps_jitcnt; long pps_stbcnt; long pps_errcnt;#endif}; static struct ntp_data tk_ntp_data[TIMEKEEPERS_MAX] = { [ 0 ... TIMEKEEPERS_MAX - 1 ] = { .tick_usec = USER_TICK_USEC, .time_state = TIME_OK, .time_status = STA_UNSYNC, .time_constant = 2, .time_maxerror = NTP_PHASE_LIMIT, .time_esterror = NTP_PHASE_LIMIT, .ntp_next_leap_sec = TIME64_MAX, },}; #define SECS_PER_DAY 86400#define MAX_TICKADJ 500LL /* usecs *//* One microsecond of phase, in plain shifted-ns (ns << NTP_SCALE_SHIFT) */#define ONE_US_NS ((s64)NSEC_PER_USEC << NTP_SCALE_SHIFT)/* Per-tick MAX_TICKADJ slew, in plain shifted-ns */#define MAX_TICKADJ_SCALED \ (((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ)#define MAX_TAI_OFFSET 100000 #ifdef CONFIG_NTP_PPS /* * The following variables are used when a pulse-per-second (PPS) signal * is available. They establish the engineering parameters of the clock * discipline loop when controlled by the PPS signal. */#define PPS_VALID 10 /* PPS signal watchdog max (s) */#define PPS_POPCORN 4 /* popcorn spike threshold (shift) */#define PPS_INTMIN 2 /* min freq interval (s) (shift) */#define PPS_INTMAX 8 /* max freq interval (s) (shift) */#define PPS_INTCOUNT 4 /* number of consecutive good intervals to increase pps_shift or consecutive bad intervals to decrease it */#define PPS_MAXWANDER 100000 /* max PPS freq wander (ns/s) */ /* * PPS kernel consumer compensates the whole phase error immediately. * Otherwise, reduce the offset by a fixed factor times the time constant. */static inline s64 ntp_offset_chunk(struct ntp_data *ntpdata, s64 offset){ if (ntpdata->time_status & STA_PPSTIME && ntpdata->time_status & STA_PPSSIGNAL) return offset; else return shift_right(offset, SHIFT_PLL + ntpdata->time_constant);} static inline void pps_reset_freq_interval(struct ntp_data *ntpdata){ /* The PPS calibration interval may end surprisingly early */ ntpdata->pps_shift = PPS_INTMIN; ntpdata->pps_intcnt = 0;} /** * pps_clear - Clears the PPS state variables * @ntpdata: Pointer to ntp data */static inline void pps_clear(struct ntp_data *ntpdata){ pps_reset_freq_interval(ntpdata); ntpdata->pps_tf[0] = 0; ntpdata->pps_tf[1] = 0; ntpdata->pps_tf[2] = 0; ntpdata->pps_fbase.tv_sec = ntpdata->pps_fbase.tv_nsec = 0; ntpdata->pps_freq = 0;} /* * Decrease pps_valid to indicate that another second has passed since the * last PPS signal. When it reaches 0, indicate that PPS signal is missing. */static inline void pps_dec_valid(struct ntp_data *ntpdata){ if (ntpdata->pps_valid > 0) { ntpdata->pps_valid--; } else { ntpdata->time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); pps_clear(ntpdata); }} static inline void pps_set_freq(struct ntp_data *ntpdata){ ntpdata->pps_freq = ntpdata->time_freq;} static inline bool is_error_status(int status){ return (status & (STA_UNSYNC|STA_CLOCKERR)) /* * PPS signal lost when either PPS time or PPS frequency * synchronization requested */ || ((status & (STA_PPSFREQ|STA_PPSTIME)) && !(status & STA_PPSSIGNAL)) /* * PPS jitter exceeded when PPS time synchronization * requested */ || ((status & (STA_PPSTIME|STA_PPSJITTER)) == (STA_PPSTIME|STA_PPSJITTER)) /* * PPS wander exceeded or calibration error when PPS * frequency synchronization requested */ || ((status & STA_PPSFREQ) && (status & (STA_PPSWANDER|STA_PPSERROR)));} static inline void pps_fill_timex(struct ntp_data *ntpdata, struct __kernel_timex *txc){ txc->ppsfreq = shift_right((ntpdata->pps_freq >> PPM_SCALE_INV_SHIFT) * PPM_SCALE_INV, NTP_SCALE_SHIFT); txc->jitter = ntpdata->pps_jitter; if (!(ntpdata->time_status & STA_NANO)) txc->jitter = ntpdata->pps_jitter / NSEC_PER_USEC; txc->shift = ntpdata->pps_shift; txc->stabil = ntpdata->pps_stabil; txc->jitcnt = ntpdata->pps_jitcnt; txc->calcnt = ntpdata->pps_calcnt; txc->errcnt = ntpdata->pps_errcnt; txc->stbcnt = ntpdata->pps_stbcnt;} #else /* !CONFIG_NTP_PPS */ static inline s64 ntp_offset_chunk(struct ntp_data *ntpdata, s64 offset){ return shift_right(offset, SHIFT_PLL + ntpdata->time_constant);} static inline void pps_reset_freq_interval(struct ntp_data *ntpdata) {}static inline void pps_clear(struct ntp_data *ntpdata) {}static inline void pps_dec_valid(struct ntp_data *ntpdata) {}static inline void pps_set_freq(struct ntp_data *ntpdata) {} static inline bool is_error_status(int status){ return status & (STA_UNSYNC|STA_CLOCKERR);} static inline void pps_fill_timex(struct ntp_data *ntpdata, struct __kernel_timex *txc){ /* PPS is not implemented, so these are zero */ txc->ppsfreq = 0; txc->jitter = 0; txc->shift = 0; txc->stabil = 0; txc->jitcnt = 0; txc->calcnt = 0; txc->errcnt = 0; txc->stbcnt = 0;} #endif /* CONFIG_NTP_PPS */ /* * Update tick_length based on tick_usec, ntp_tick_adj and time_freq: */static void ntp_update_frequency(struct ntp_data *ntpdata){ u64 second_length, new_base, tick_usec = (u64)ntpdata->tick_usec; second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << NTP_SCALE_SHIFT; second_length += ntpdata->ntp_tick_adj; second_length += ntpdata->cs_tick_adj; second_length += ntpdata->time_freq; new_base = div_u64(second_length, NTP_INTERVAL_FREQ); /* * Don't wait for the next second_overflow, apply the change to the * tick length immediately: */ ntpdata->tick_length = new_base;} static inline s64 ntp_update_offset_fll(struct ntp_data *ntpdata, s64 offset64, long secs){ ntpdata->time_status &= ~STA_MODE; if (secs < MINSEC) return 0; if (!(ntpdata->time_status & STA_FLL) && (secs <= MAXSEC)) return 0; ntpdata->time_status |= STA_MODE; return div64_long(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs);} static void ntp_update_offset(struct ntp_data *ntpdata, long offset){ s64 freq_adj, offset64; long secs, real_secs; if (!(ntpdata->time_status & STA_PLL)) return; if (!(ntpdata->time_status & STA_NANO)) { /* Make sure the multiplication below won't overflow */ offset = clamp(offset, -USEC_PER_SEC, USEC_PER_SEC); offset *= NSEC_PER_USEC; } /* Scale the phase adjustment and clamp to the operating range. */ offset = clamp(offset, -MAXPHASE, MAXPHASE); /* * Select how the frequency is to be controlled * and in which mode (PLL or FLL). */ real_secs = ktime_get_ntp_seconds(ntpdata - tk_ntp_data); secs = (long)(real_secs - ntpdata->time_reftime); if (unlikely(ntpdata->time_status & STA_FREQHOLD)) secs = 0; ntpdata->time_reftime = real_secs; offset64 = offset; freq_adj = ntp_update_offset_fll(ntpdata, offset64, secs); /* * Clamp update interval to reduce PLL gain with low * sampling rate (e.g. intermittent network connection) * to avoid instability. */ if (unlikely(secs > 1 << (SHIFT_PLL + 1 + ntpdata->time_constant))) secs = 1 << (SHIFT_PLL + 1 + ntpdata->time_constant); freq_adj += (offset64 * secs) << (NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + ntpdata->time_constant)); freq_adj = min(freq_adj + ntpdata->time_freq, MAXFREQ_SCALED); ntpdata->time_freq = max(freq_adj, -MAXFREQ_SCALED); ntpdata->time_offset = div_s64(offset64 << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ);} static void __ntp_clear(struct ntp_data *ntpdata){ /* Stop active adjtime() */ ntpdata->time_adjust = 0; ntpdata->time_adjust_frac = 0; ntpdata->time_status |= STA_UNSYNC; ntpdata->time_maxerror = NTP_PHASE_LIMIT; ntpdata->time_esterror = NTP_PHASE_LIMIT; ntp_update_frequency(ntpdata); ntpdata->time_offset = 0; ntpdata->skew_delta = 0; ntpdata->ntp_next_leap_sec = TIME64_MAX; /* Clear PPS state variables */ pps_clear(ntpdata);} /** * ntp_clear - Clear NTP state and set the clocksource quantisation adjustment * @tkid: Timekeeper ID * @cs_tick_adj: Per-second adjustment in ns << NTP_SCALE_SHIFT * * The timekeeping core uses an integer number of cycles (@cycle_interval) * per NTP interval, so the real time that interval represents differs from * the nominal NTP_INTERVAL_LENGTH by up to half a counter period. Folding * this fixed offset into @cs_tick_adj makes it an explicit part of the NTP * tick_length computation in ntp.c, instead of being applied during * timekeeping accumulation where the NTP code never saw it. Like * @ntp_tick_adj it stays internal to the kernel; userspace still sees the * nominal tick via adjtimex. NTP retains its full symmetric ±MAXFREQ range * around the corrected base rate. * * Called whenever the clocksource is (re)configured, which is also when the * rest of the NTP state must be cleared, so the two are done together. */void ntp_clear(unsigned int tkid, s64 cs_tick_adj){ tk_ntp_data[tkid].cs_tick_adj = cs_tick_adj; __ntp_clear(&tk_ntp_data[tkid]);} u64 ntp_tick_length(unsigned int tkid){ return tk_ntp_data[tkid].tick_length;} s64 ntp_get_skew_delta(unsigned int tkid){ return tk_ntp_data[tkid].skew_delta;} /* Sign of @x as +1 or -1 (zero counts as positive; callers pass nonzero). */static inline int signof(s64 x){ return x < 0 ? -1 : 1;} static s64 ntp_drain_time_offset(unsigned int tkid, s64 amount){ struct ntp_data *ntpdata = &tk_ntp_data[tkid]; /* Only drain if amount and time_offset have the same sign */ if (!amount || signof(amount) != signof(ntpdata->time_offset)) return amount; /* Clamp: don't overshoot zero */ if (abs(amount) > abs(ntpdata->time_offset)) { s64 undrained = amount - ntpdata->time_offset; ntpdata->time_offset = 0; return undrained; } ntpdata->time_offset -= amount; return 0;} /* * Drain the legacy adjtime() correction (time_adjust) as it is delivered. * * @amount is the total intentional per-tick skew for this accumulation * (skew_delta << shift), in time_offset units (shifted_ns / HZ); it covers * both the exponential time_offset slew and the linear adjtime slew. This * function claims only the adjtime share — capped at the MAX_TICKADJ rate — * and returns the remainder for ntp_drain_time_offset(). * * time_adjust is in whole µs. The sub-µs remainder being delivered lives in * time_adjust_frac (plain shifted-ns, i.e. ns << NTP_SCALE_SHIFT -- unlike * time_offset these are NOT pre-divided by HZ); we top it up by borrowing * whole microseconds from time_adjust as the drain consumes it. */static s64 ntp_drain_time_adjust(unsigned int tkid, s64 amount, unsigned int shift){ struct ntp_data *ntpdata = &tk_ntp_data[tkid]; /* Sign reference: time_adjust if any whole us remain, else the drawer */ s64 ref = ntpdata->time_adjust ? (s64)ntpdata->time_adjust : ntpdata->time_adjust_frac; s64 deliver, deficit, claimed; if (!amount || !ref || signof(amount) != signof(ref)) return amount; /* * Phase to deliver this accumulation, in plain shifted-ns. The drain * @amount is in ÷HZ units, so multiply by HZ first, then clamp to the * MAX_TICKADJ rate (MAX_TICKADJ_SCALED is the per-tick slew in * shifted-ns). Multiply-then-clamp avoids an s64 divide for the cap. */ deliver = min(abs(amount) * NTP_INTERVAL_FREQ, (s64)MAX_TICKADJ_SCALED << shift); /* Top up the sub-µs drawer from whole-µs time_adjust as needed */ deficit = deliver - abs(ntpdata->time_adjust_frac); if (deficit > 0 && ntpdata->time_adjust) { long borrow = div64_u64(deficit + ONE_US_NS - 1, ONE_US_NS); if (ntpdata->time_adjust > 0) { borrow = min(borrow, ntpdata->time_adjust); ntpdata->time_adjust -= borrow; ntpdata->time_adjust_frac += (s64)borrow * ONE_US_NS; } else { /* Clamp without negating time_adjust (UB for LONG_MIN) */ if (ntpdata->time_adjust > -borrow) borrow = -ntpdata->time_adjust; ntpdata->time_adjust += borrow; ntpdata->time_adjust_frac -= (s64)borrow * ONE_US_NS; } } /* Never deliver more than the drawer holds */ deliver = min(deliver, abs(ntpdata->time_adjust_frac)); if (ntpdata->time_adjust_frac > 0) ntpdata->time_adjust_frac -= deliver; else ntpdata->time_adjust_frac += deliver; /* Return the unclaimed remainder in ÷HZ drain units for time_offset */ claimed = div_s64(deliver, NTP_INTERVAL_FREQ); return amount - signof(amount) * claimed;} /* * Drain one accumulation's worth of intentional skew as it is delivered. * * @amount is the total intentional per-tick skew for this accumulation * (skew_delta << shift), in time_offset units (shifted_ns / HZ). The * adjtime() linear share is taken from time_adjust first (capped at the * MAX_TICKADJ rate, hence @shift), then the exponential remainder from * time_offset. Returns the amount actually claimed (same ÷HZ units). */s64 ntp_drain_skew(unsigned int tkid, s64 amount, unsigned int shift){Lines 1–500 of 1352. Load more
// SPDX-License-Identifier: GPL-2.0 /* * NTP state machine interfaces and logic. * * This code was mainly moved from kernel/timer.c and kernel/time.c * Please see those files for relevant copyright info and historical * changelogs. */ #include <linux/capability.h> #include <linux/clocksource.h> #include <linux/workqueue.h> #include <linux/hrtimer.h> #include <linux/jiffies.h> #include <linux/math64.h> #include <linux/timex.h> #include <linux/time.h> #include <linux/mm.h> #include <linux/module.h> #include <linux/rtc.h> #include <linux/audit.h> #include <linux/timekeeper_internal.h> #include "ntp_internal.h" #include "timekeeping_internal.h" /** * struct ntp_data - Structure holding all NTP related state * @tick_usec: USER_HZ period in microseconds * @tick_length: Tick length in ns << NTP_SCALE_SHIFT * @time_state: State of the clock synchronization * @time_status: Clock status bits * @time_offset: Time adjustment in nanoseconds * @skew_delta: Per-tick phase slew rate for the coming second, in * @time_offset units (shifted-ns / HZ). Set by * second_overflow(). * @time_constant: PLL time constant * @time_maxerror: Maximum error in microseconds holding the NTP sync distance * (NTP dispersion + delay / 2) * @time_esterror: Estimated error in microseconds holding NTP dispersion * @time_freq: Frequency offset scaled nsecs/secs * @time_reftime: Time at last adjustment in seconds * @time_adjust: Adjustment value * @time_adjust_frac: Sub-microsecond remainder of @time_adjust being * delivered, in ns << NTP_SCALE_SHIFT (not divided by HZ). * @ntp_tick_adj: Constant boot-param configurable NTP tick adjustment (upscaled) * @cs_tick_adj: Fixed per-second adjustment compensating for the difference * between the nominal NTP interval and the real time taken * by the clocksource's integer @cycle_interval (upscaled). * Set by the timekeeping core via ntp_clear(). * @ntp_next_leap_sec: Second value of the next pending leapsecond, or TIME64_MAX if no leap * * @pps_valid: PPS signal watchdog counter * @pps_tf: PPS phase median filter * @pps_jitter: PPS current jitter in nanoseconds * @pps_fbase: PPS beginning of the last freq interval * @pps_shift: PPS current interval duration in seconds (shift value) * @pps_intcnt: PPS interval counter * @pps_freq: PPS frequency offset in scaled ns/s * @pps_stabil: PPS current stability in scaled ns/s * @pps_calcnt: PPS monitor: calibration intervals * @pps_jitcnt: PPS monitor: jitter limit exceeded * @pps_stbcnt: PPS monitor: stability limit exceeded * @pps_errcnt: PPS monitor: calibration errors * * Protected by the timekeeping locks. */ struct ntp_data { unsigned long tick_usec; u64 tick_length; int time_state; int time_status; s64 time_offset; s64 skew_delta; long time_constant; long time_maxerror; long time_esterror; s64 time_freq; time64_t time_reftime; long time_adjust; s64 time_adjust_frac; s64 ntp_tick_adj; s64 cs_tick_adj; time64_t ntp_next_leap_sec; #ifdef CONFIG_NTP_PPS int pps_valid; long pps_tf[3]; long pps_jitter; struct timespec64 pps_fbase; int pps_shift; int pps_intcnt; s64 pps_freq; long pps_stabil; long pps_calcnt; long pps_jitcnt; long pps_stbcnt; long pps_errcnt; #endif }; static struct ntp_data tk_ntp_data[TIMEKEEPERS_MAX] = { [ 0 ... TIMEKEEPERS_MAX - 1 ] = { .tick_usec = USER_TICK_USEC, .time_state = TIME_OK, .time_status = STA_UNSYNC, .time_constant = 2, .time_maxerror = NTP_PHASE_LIMIT, .time_esterror = NTP_PHASE_LIMIT, .ntp_next_leap_sec = TIME64_MAX, }, }; #define SECS_PER_DAY 86400 #define MAX_TICKADJ 500LL /* usecs */ /* One microsecond of phase, in plain shifted-ns (ns << NTP_SCALE_SHIFT) */ #define ONE_US_NS ((s64)NSEC_PER_USEC << NTP_SCALE_SHIFT) /* Per-tick MAX_TICKADJ slew, in plain shifted-ns */ #define MAX_TICKADJ_SCALED \ (((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ) #define MAX_TAI_OFFSET 100000 #ifdef CONFIG_NTP_PPS /* * The following variables are used when a pulse-per-second (PPS) signal * is available. They establish the engineering parameters of the clock * discipline loop when controlled by the PPS signal. */ #define PPS_VALID 10 /* PPS signal watchdog max (s) */ #define PPS_POPCORN 4 /* popcorn spike threshold (shift) */ #define PPS_INTMIN 2 /* min freq interval (s) (shift) */ #define PPS_INTMAX 8 /* max freq interval (s) (shift) */ #define PPS_INTCOUNT 4 /* number of consecutive good intervals to increase pps_shift or consecutive bad intervals to decrease it */ #define PPS_MAXWANDER 100000 /* max PPS freq wander (ns/s) */ /* * PPS kernel consumer compensates the whole phase error immediately. * Otherwise, reduce the offset by a fixed factor times the time constant. */ static inline s64 ntp_offset_chunk(struct ntp_data *ntpdata, s64 offset) { if (ntpdata->time_status & STA_PPSTIME && ntpdata->time_status & STA_PPSSIGNAL) return offset; else return shift_right(offset, SHIFT_PLL + ntpdata->time_constant); } static inline void pps_reset_freq_interval(struct ntp_data *ntpdata) { /* The PPS calibration interval may end surprisingly early */ ntpdata->pps_shift = PPS_INTMIN; ntpdata->pps_intcnt = 0; } /** * pps_clear - Clears the PPS state variables * @ntpdata: Pointer to ntp data */ static inline void pps_clear(struct ntp_data *ntpdata) { pps_reset_freq_interval(ntpdata); ntpdata->pps_tf[0] = 0; ntpdata->pps_tf[1] = 0; ntpdata->pps_tf[2] = 0; ntpdata->pps_fbase.tv_sec = ntpdata->pps_fbase.tv_nsec = 0; ntpdata->pps_freq = 0; } /* * Decrease pps_valid to indicate that another second has passed since the * last PPS signal. When it reaches 0, indicate that PPS signal is missing. */ static inline void pps_dec_valid(struct ntp_data *ntpdata) { if (ntpdata->pps_valid > 0) { ntpdata->pps_valid--; } else { ntpdata->time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | STA_PPSERROR); pps_clear(ntpdata); } } static inline void pps_set_freq(struct ntp_data *ntpdata) { ntpdata->pps_freq = ntpdata->time_freq; } static inline bool is_error_status(int status) { return (status & (STA_UNSYNC|STA_CLOCKERR)) /* * PPS signal lost when either PPS time or PPS frequency * synchronization requested */ || ((status & (STA_PPSFREQ|STA_PPSTIME)) && !(status & STA_PPSSIGNAL)) /* * PPS jitter exceeded when PPS time synchronization * requested */ || ((status & (STA_PPSTIME|STA_PPSJITTER)) == (STA_PPSTIME|STA_PPSJITTER)) /* * PPS wander exceeded or calibration error when PPS * frequency synchronization requested */ || ((status & STA_PPSFREQ) && (status & (STA_PPSWANDER|STA_PPSERROR))); } static inline void pps_fill_timex(struct ntp_data *ntpdata, struct __kernel_timex *txc) { txc->ppsfreq = shift_right((ntpdata->pps_freq >> PPM_SCALE_INV_SHIFT) * PPM_SCALE_INV, NTP_SCALE_SHIFT); txc->jitter = ntpdata->pps_jitter; if (!(ntpdata->time_status & STA_NANO)) txc->jitter = ntpdata->pps_jitter / NSEC_PER_USEC; txc->shift = ntpdata->pps_shift; txc->stabil = ntpdata->pps_stabil; txc->jitcnt = ntpdata->pps_jitcnt; txc->calcnt = ntpdata->pps_calcnt; txc->errcnt = ntpdata->pps_errcnt; txc->stbcnt = ntpdata->pps_stbcnt; } #else /* !CONFIG_NTP_PPS */ static inline s64 ntp_offset_chunk(struct ntp_data *ntpdata, s64 offset) { return shift_right(offset, SHIFT_PLL + ntpdata->time_constant); } static inline void pps_reset_freq_interval(struct ntp_data *ntpdata) {} static inline void pps_clear(struct ntp_data *ntpdata) {} static inline void pps_dec_valid(struct ntp_data *ntpdata) {} static inline void pps_set_freq(struct ntp_data *ntpdata) {} static inline bool is_error_status(int status) { return status & (STA_UNSYNC|STA_CLOCKERR); } static inline void pps_fill_timex(struct ntp_data *ntpdata, struct __kernel_timex *txc) { /* PPS is not implemented, so these are zero */ txc->ppsfreq = 0; txc->jitter = 0; txc->shift = 0; txc->stabil = 0; txc->jitcnt = 0; txc->calcnt = 0; txc->errcnt = 0; txc->stbcnt = 0; } #endif /* CONFIG_NTP_PPS */ /* * Update tick_length based on tick_usec, ntp_tick_adj and time_freq: */ static void ntp_update_frequency(struct ntp_data *ntpdata) { u64 second_length, new_base, tick_usec = (u64)ntpdata->tick_usec; second_length = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << NTP_SCALE_SHIFT; second_length += ntpdata->ntp_tick_adj; second_length += ntpdata->cs_tick_adj; second_length += ntpdata->time_freq; new_base = div_u64(second_length, NTP_INTERVAL_FREQ); /* * Don't wait for the next second_overflow, apply the change to the * tick length immediately: */ ntpdata->tick_length = new_base; } static inline s64 ntp_update_offset_fll(struct ntp_data *ntpdata, s64 offset64, long secs) { ntpdata->time_status &= ~STA_MODE; if (secs < MINSEC) return 0; if (!(ntpdata->time_status & STA_FLL) && (secs <= MAXSEC)) return 0; ntpdata->time_status |= STA_MODE; return div64_long(offset64 << (NTP_SCALE_SHIFT - SHIFT_FLL), secs); } static void ntp_update_offset(struct ntp_data *ntpdata, long offset) { s64 freq_adj, offset64; long secs, real_secs; if (!(ntpdata->time_status & STA_PLL)) return; if (!(ntpdata->time_status & STA_NANO)) { /* Make sure the multiplication below won't overflow */ offset = clamp(offset, -USEC_PER_SEC, USEC_PER_SEC); offset *= NSEC_PER_USEC; } /* Scale the phase adjustment and clamp to the operating range. */ offset = clamp(offset, -MAXPHASE, MAXPHASE); /* * Select how the frequency is to be controlled * and in which mode (PLL or FLL). */ real_secs = ktime_get_ntp_seconds(ntpdata - tk_ntp_data); secs = (long)(real_secs - ntpdata->time_reftime); if (unlikely(ntpdata->time_status & STA_FREQHOLD)) secs = 0; ntpdata->time_reftime = real_secs; offset64 = offset; freq_adj = ntp_update_offset_fll(ntpdata, offset64, secs); /* * Clamp update interval to reduce PLL gain with low * sampling rate (e.g. intermittent network connection) * to avoid instability. */ if (unlikely(secs > 1 << (SHIFT_PLL + 1 + ntpdata->time_constant))) secs = 1 << (SHIFT_PLL + 1 + ntpdata->time_constant); freq_adj += (offset64 * secs) << (NTP_SCALE_SHIFT - 2 * (SHIFT_PLL + 2 + ntpdata->time_constant)); freq_adj = min(freq_adj + ntpdata->time_freq, MAXFREQ_SCALED); ntpdata->time_freq = max(freq_adj, -MAXFREQ_SCALED); ntpdata->time_offset = div_s64(offset64 << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ); } static void __ntp_clear(struct ntp_data *ntpdata) { /* Stop active adjtime() */ ntpdata->time_adjust = 0; ntpdata->time_adjust_frac = 0; ntpdata->time_status |= STA_UNSYNC; ntpdata->time_maxerror = NTP_PHASE_LIMIT; ntpdata->time_esterror = NTP_PHASE_LIMIT; ntp_update_frequency(ntpdata); ntpdata->time_offset = 0; ntpdata->skew_delta = 0; ntpdata->ntp_next_leap_sec = TIME64_MAX; /* Clear PPS state variables */ pps_clear(ntpdata); } /** * ntp_clear - Clear NTP state and set the clocksource quantisation adjustment * @tkid: Timekeeper ID * @cs_tick_adj: Per-second adjustment in ns << NTP_SCALE_SHIFT * * The timekeeping core uses an integer number of cycles (@cycle_interval) * per NTP interval, so the real time that interval represents differs from * the nominal NTP_INTERVAL_LENGTH by up to half a counter period. Folding * this fixed offset into @cs_tick_adj makes it an explicit part of the NTP * tick_length computation in ntp.c, instead of being applied during * timekeeping accumulation where the NTP code never saw it. Like * @ntp_tick_adj it stays internal to the kernel; userspace still sees the * nominal tick via adjtimex. NTP retains its full symmetric ±MAXFREQ range * around the corrected base rate. * * Called whenever the clocksource is (re)configured, which is also when the * rest of the NTP state must be cleared, so the two are done together. */ void ntp_clear(unsigned int tkid, s64 cs_tick_adj) { tk_ntp_data[tkid].cs_tick_adj = cs_tick_adj; __ntp_clear(&tk_ntp_data[tkid]); } u64 ntp_tick_length(unsigned int tkid) { return tk_ntp_data[tkid].tick_length; } s64 ntp_get_skew_delta(unsigned int tkid) { return tk_ntp_data[tkid].skew_delta; } /* Sign of @x as +1 or -1 (zero counts as positive; callers pass nonzero). */ static inline int signof(s64 x) { return x < 0 ? -1 : 1; } static s64 ntp_drain_time_offset(unsigned int tkid, s64 amount) { struct ntp_data *ntpdata = &tk_ntp_data[tkid]; /* Only drain if amount and time_offset have the same sign */ if (!amount || signof(amount) != signof(ntpdata->time_offset)) return amount; /* Clamp: don't overshoot zero */ if (abs(amount) > abs(ntpdata->time_offset)) { s64 undrained = amount - ntpdata->time_offset; ntpdata->time_offset = 0; return undrained; } ntpdata->time_offset -= amount; return 0; } /* * Drain the legacy adjtime() correction (time_adjust) as it is delivered. * * @amount is the total intentional per-tick skew for this accumulation * (skew_delta << shift), in time_offset units (shifted_ns / HZ); it covers * both the exponential time_offset slew and the linear adjtime slew. This * function claims only the adjtime share — capped at the MAX_TICKADJ rate — * and returns the remainder for ntp_drain_time_offset(). * * time_adjust is in whole µs. The sub-µs remainder being delivered lives in * time_adjust_frac (plain shifted-ns, i.e. ns << NTP_SCALE_SHIFT -- unlike * time_offset these are NOT pre-divided by HZ); we top it up by borrowing * whole microseconds from time_adjust as the drain consumes it. */ static s64 ntp_drain_time_adjust(unsigned int tkid, s64 amount, unsigned int shift) { struct ntp_data *ntpdata = &tk_ntp_data[tkid]; /* Sign reference: time_adjust if any whole us remain, else the drawer */ s64 ref = ntpdata->time_adjust ? (s64)ntpdata->time_adjust : ntpdata->time_adjust_frac; s64 deliver, deficit, claimed; if (!amount || !ref || signof(amount) != signof(ref)) return amount; /* * Phase to deliver this accumulation, in plain shifted-ns. The drain * @amount is in ÷HZ units, so multiply by HZ first, then clamp to the * MAX_TICKADJ rate (MAX_TICKADJ_SCALED is the per-tick slew in * shifted-ns). Multiply-then-clamp avoids an s64 divide for the cap. */ deliver = min(abs(amount) * NTP_INTERVAL_FREQ, (s64)MAX_TICKADJ_SCALED << shift); /* Top up the sub-µs drawer from whole-µs time_adjust as needed */ deficit = deliver - abs(ntpdata->time_adjust_frac); if (deficit > 0 && ntpdata->time_adjust) { long borrow = div64_u64(deficit + ONE_US_NS - 1, ONE_US_NS); if (ntpdata->time_adjust > 0) { borrow = min(borrow, ntpdata->time_adjust); ntpdata->time_adjust -= borrow; ntpdata->time_adjust_frac += (s64)borrow * ONE_US_NS; } else { /* Clamp without negating time_adjust (UB for LONG_MIN) */ if (ntpdata->time_adjust > -borrow) borrow = -ntpdata->time_adjust; ntpdata->time_adjust += borrow; ntpdata->time_adjust_frac -= (s64)borrow * ONE_US_NS; } } /* Never deliver more than the drawer holds */ deliver = min(deliver, abs(ntpdata->time_adjust_frac)); if (ntpdata->time_adjust_frac > 0) ntpdata->time_adjust_frac -= deliver; else ntpdata->time_adjust_frac += deliver; /* Return the unclaimed remainder in ÷HZ drain units for time_offset */ claimed = div_s64(deliver, NTP_INTERVAL_FREQ); return amount - signof(amount) * claimed; } /* * Drain one accumulation's worth of intentional skew as it is delivered. * * @amount is the total intentional per-tick skew for this accumulation * (skew_delta << shift), in time_offset units (shifted_ns / HZ). The * adjtime() linear share is taken from time_adjust first (capped at the * MAX_TICKADJ rate, hence @shift), then the exponential remainder from * time_offset. Returns the amount actually claimed (same ÷HZ units). */ s64 ntp_drain_skew(unsigned int tkid, s64 amount, unsigned int shift) {