This is a note to let you know that I've just added the patch titled ntp: Introduce struct ntp_data to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: ntp-introduce-struct-ntp_data.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 6018e1b206968dd5a882e341c5582d81b808ffa5 Author: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Date: Wed Sep 11 15:17:43 2024 +0200 ntp: Introduce struct ntp_data [ Upstream commit 68f66f97c5689825012877f58df65964056d4b5d ] All NTP data is held in static variables. That prevents the NTP code from being reuasble for non-system time timekeepers, e.g. per PTP clock timekeeping. Introduce struct ntp_data and move tick_usec into it for a start. No functional change. Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Signed-off-by: Anna-Maria Behnsen <anna-maria@xxxxxxxxxxxxx> Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Acked-by: John Stultz <jstultz@xxxxxxxxxx> Link: https://lore.kernel.org/all/20240911-devel-anna-maria-b4-timers-ptp-ntp-v1-7-2d52f4e13476@xxxxxxxxxxxxx Stable-dep-of: f5807b0606da ("ntp: Remove invalid cast in time offset math") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 477cb08062bc5..0222f8e460810 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -22,16 +22,19 @@ #include "ntp_internal.h" #include "timekeeping_internal.h" - -/* - * NTP timekeeping variables: +/** + * struct ntp_data - Structure holding all NTP related state + * @tick_usec: USER_HZ period in microseconds * - * Note: All of the NTP state is protected by the timekeeping locks. + * Protected by the timekeeping locks. */ +struct ntp_data { + unsigned long tick_usec; +}; - -/* USER_HZ period (usecs): */ -static unsigned long tick_usec = USER_TICK_USEC; +static struct ntp_data tk_ntp_data = { + .tick_usec = USER_TICK_USEC, +}; static u64 tick_length; static u64 tick_length_base; @@ -245,13 +248,11 @@ static inline void pps_fill_timex(struct __kernel_timex *txc) * Update tick_length and tick_length_base, based on tick_usec, ntp_tick_adj and * time_freq: */ -static void ntp_update_frequency(void) +static void ntp_update_frequency(struct ntp_data *ntpdata) { - u64 second_length; - u64 new_base; + 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 = (u64)(tick_usec * NSEC_PER_USEC * USER_HZ) << NTP_SCALE_SHIFT; second_length += ntp_tick_adj; second_length += time_freq; @@ -330,10 +331,7 @@ static void ntp_update_offset(long offset) time_offset = div_s64(offset64 << NTP_SCALE_SHIFT, NTP_INTERVAL_FREQ); } -/** - * ntp_clear - Clears the NTP state variables - */ -void ntp_clear(void) +static void __ntp_clear(struct ntp_data *ntpdata) { /* Stop active adjtime() */ time_adjust = 0; @@ -341,7 +339,7 @@ void ntp_clear(void) time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - ntp_update_frequency(); + ntp_update_frequency(ntpdata); tick_length = tick_length_base; time_offset = 0; @@ -351,6 +349,14 @@ void ntp_clear(void) pps_clear(); } +/** + * ntp_clear - Clears the NTP state variables + */ +void ntp_clear(void) +{ + __ntp_clear(&tk_ntp_data); +} + u64 ntp_tick_length(void) { @@ -698,7 +704,7 @@ static inline void process_adj_status(const struct __kernel_timex *txc) } -static inline void process_adjtimex_modes(const struct __kernel_timex *txc, +static inline void process_adjtimex_modes(struct ntp_data *ntpdata, const struct __kernel_timex *txc, s32 *time_tai) { if (txc->modes & ADJ_STATUS) @@ -739,13 +745,12 @@ static inline void process_adjtimex_modes(const struct __kernel_timex *txc, ntp_update_offset(txc->offset); if (txc->modes & ADJ_TICK) - tick_usec = txc->tick; + ntpdata->tick_usec = txc->tick; if (txc->modes & (ADJ_TICK|ADJ_FREQUENCY|ADJ_OFFSET)) - ntp_update_frequency(); + ntp_update_frequency(ntpdata); } - /* * adjtimex() mainly allows reading (and writing, if superuser) of * kernel time-keeping variables. used by xntpd. @@ -753,6 +758,7 @@ static inline void process_adjtimex_modes(const struct __kernel_timex *txc, int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts, s32 *time_tai, struct audit_ntp_data *ad) { + struct ntp_data *ntpdata = &tk_ntp_data; int result; if (txc->modes & ADJ_ADJTIME) { @@ -761,7 +767,7 @@ int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts, if (!(txc->modes & ADJ_OFFSET_READONLY)) { /* adjtime() is independent from ntp_adjtime() */ time_adjust = txc->offset; - ntp_update_frequency(); + ntp_update_frequency(ntpdata); audit_ntp_set_old(ad, AUDIT_NTP_ADJUST, save_adjust); audit_ntp_set_new(ad, AUDIT_NTP_ADJUST, time_adjust); @@ -774,15 +780,15 @@ int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts, audit_ntp_set_old(ad, AUDIT_NTP_FREQ, time_freq); audit_ntp_set_old(ad, AUDIT_NTP_STATUS, time_status); audit_ntp_set_old(ad, AUDIT_NTP_TAI, *time_tai); - audit_ntp_set_old(ad, AUDIT_NTP_TICK, tick_usec); + audit_ntp_set_old(ad, AUDIT_NTP_TICK, ntpdata->tick_usec); - process_adjtimex_modes(txc, time_tai); + process_adjtimex_modes(ntpdata, txc, time_tai); audit_ntp_set_new(ad, AUDIT_NTP_OFFSET, time_offset); audit_ntp_set_new(ad, AUDIT_NTP_FREQ, time_freq); audit_ntp_set_new(ad, AUDIT_NTP_STATUS, time_status); audit_ntp_set_new(ad, AUDIT_NTP_TAI, *time_tai); - audit_ntp_set_new(ad, AUDIT_NTP_TICK, tick_usec); + audit_ntp_set_new(ad, AUDIT_NTP_TICK, ntpdata->tick_usec); } txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ, @@ -803,7 +809,7 @@ int __do_adjtimex(struct __kernel_timex *txc, const struct timespec64 *ts, txc->constant = time_constant; txc->precision = 1; txc->tolerance = MAXFREQ_SCALED / PPM_SCALE; - txc->tick = tick_usec; + txc->tick = ntpdata->tick_usec; txc->tai = *time_tai; /* Fill PPS status fields */ @@ -924,7 +930,7 @@ static inline void pps_inc_freq_interval(void) * too long, the data are discarded. * Returns the difference between old and new frequency values. */ -static long hardpps_update_freq(struct pps_normtime freq_norm) +static long hardpps_update_freq(struct ntp_data *ntpdata, struct pps_normtime freq_norm) { long delta, delta_mod; s64 ftemp; @@ -971,7 +977,7 @@ static long hardpps_update_freq(struct pps_normtime freq_norm) /* If enabled, the system clock frequency is updated */ if ((time_status & STA_PPSFREQ) && !(time_status & STA_FREQHOLD)) { time_freq = pps_freq; - ntp_update_frequency(); + ntp_update_frequency(ntpdata); } return delta; @@ -1022,6 +1028,7 @@ static void hardpps_update_phase(long error) void __hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts) { struct pps_normtime pts_norm, freq_norm; + struct ntp_data *ntpdata = &tk_ntp_data; pts_norm = pps_normalize_ts(*phase_ts); @@ -1062,7 +1069,7 @@ void __hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_t pps_calcnt++; /* Restart the frequency calibration interval */ pps_fbase = *raw_ts; - hardpps_update_freq(freq_norm); + hardpps_update_freq(ntpdata, freq_norm); } hardpps_update_phase(pts_norm.nsec);