Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ntp/pps: use timespec64 for hardpps()

There is only one user of the hardpps function in the kernel, so
it makes sense to atomically change it over to using 64-bit
timestamps for y2038 safety. In the hardpps implementation,
we also need to change the pps_normtime structure, which is
similar to struct timespec and also requires a 64-bit
seconds portion.

This introduces two temporary variables in pps_kc_event() to
do the conversion, they will be removed again in the next step,
which seemed preferable to having a larger patch changing it
all at the same time.

Acked-by: Richard Cochran <richardcochran@gmail.com>
Acked-by: David S. Miller <davem@davemloft.net>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>

authored by

Arnd Bergmann and committed by
John Stultz
7ec88e4b 9ffecb10

+12 -10
+3 -1
drivers/pps/kc.c
··· 113 113 int event) 114 114 { 115 115 unsigned long flags; 116 + struct timespec64 real = timespec_to_timespec64(ts->ts_real); 117 + struct timespec64 raw = timespec_to_timespec64(ts->ts_raw); 116 118 117 119 /* Pass some events to kernel consumer if activated */ 118 120 spin_lock_irqsave(&pps_kc_hardpps_lock, flags); 119 121 if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode) 120 - hardpps(&ts->ts_real, &ts->ts_raw); 122 + hardpps(&real, &raw); 121 123 spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags); 122 124 }
+1 -1
include/linux/timex.h
··· 152 152 #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) 153 153 154 154 extern int do_adjtimex(struct timex *); 155 - extern void hardpps(const struct timespec *, const struct timespec *); 155 + extern void hardpps(const struct timespec64 *, const struct timespec64 *); 156 156 157 157 int read_current_timer(unsigned long *timer_val); 158 158 void ntp_notify_cmos_timer(void);
+6 -6
kernel/time/ntp.c
··· 99 99 static int pps_valid; /* signal watchdog counter */ 100 100 static long pps_tf[3]; /* phase median filter */ 101 101 static long pps_jitter; /* current jitter (ns) */ 102 - static struct timespec pps_fbase; /* beginning of the last freq interval */ 102 + static struct timespec64 pps_fbase; /* beginning of the last freq interval */ 103 103 static int pps_shift; /* current interval duration (s) (shift) */ 104 104 static int pps_intcnt; /* interval counter */ 105 105 static s64 pps_freq; /* frequency offset (scaled ns/s) */ ··· 773 773 * pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] 774 774 * while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */ 775 775 struct pps_normtime { 776 - __kernel_time_t sec; /* seconds */ 776 + s64 sec; /* seconds */ 777 777 long nsec; /* nanoseconds */ 778 778 }; 779 779 780 780 /* normalize the timestamp so that nsec is in the 781 781 ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval */ 782 - static inline struct pps_normtime pps_normalize_ts(struct timespec ts) 782 + static inline struct pps_normtime pps_normalize_ts(struct timespec64 ts) 783 783 { 784 784 struct pps_normtime norm = { 785 785 .sec = ts.tv_sec, ··· 861 861 pps_errcnt++; 862 862 pps_dec_freq_interval(); 863 863 printk_deferred(KERN_ERR 864 - "hardpps: PPSERROR: interval too long - %ld s\n", 864 + "hardpps: PPSERROR: interval too long - %lld s\n", 865 865 freq_norm.sec); 866 866 return 0; 867 867 } ··· 948 948 * This code is based on David Mills's reference nanokernel 949 949 * implementation. It was mostly rewritten but keeps the same idea. 950 950 */ 951 - void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) 951 + void __hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts) 952 952 { 953 953 struct pps_normtime pts_norm, freq_norm; 954 954 ··· 969 969 } 970 970 971 971 /* ok, now we have a base for frequency calculation */ 972 - freq_norm = pps_normalize_ts(timespec_sub(*raw_ts, pps_fbase)); 972 + freq_norm = pps_normalize_ts(timespec64_sub(*raw_ts, pps_fbase)); 973 973 974 974 /* check that the signal is in the range 975 975 * [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */
+1 -1
kernel/time/ntp_internal.h
··· 9 9 extern int second_overflow(unsigned long secs); 10 10 extern int ntp_validate_timex(struct timex *); 11 11 extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); 12 - extern void __hardpps(const struct timespec *, const struct timespec *); 12 + extern void __hardpps(const struct timespec64 *, const struct timespec64 *); 13 13 #endif /* _LINUX_NTP_INTERNAL_H */
+1 -1
kernel/time/timekeeping.c
··· 2025 2025 /** 2026 2026 * hardpps() - Accessor function to NTP __hardpps function 2027 2027 */ 2028 - void hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) 2028 + void hardpps(const struct timespec64 *phase_ts, const struct timespec64 *raw_ts) 2029 2029 { 2030 2030 unsigned long flags; 2031 2031