diff options
author | Arnd Bergmann <arnd@arndb.de> | 2015-09-28 16:21:28 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2015-10-01 12:57:59 -0400 |
commit | 7ec88e4be461590b5a3817460c34603f76d9b3ae (patch) | |
tree | 00bcd8cf85a86a36c91e3e1d4c039a9ae491f770 | |
parent | 9ffecb10283508260936b96022d4ee43a7798b4c (diff) |
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>
-rw-r--r-- | drivers/pps/kc.c | 4 | ||||
-rw-r--r-- | include/linux/timex.h | 2 | ||||
-rw-r--r-- | kernel/time/ntp.c | 12 | ||||
-rw-r--r-- | kernel/time/ntp_internal.h | 2 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 2 |
5 files changed, 12 insertions, 10 deletions
diff --git a/drivers/pps/kc.c b/drivers/pps/kc.c index e219db1f1c84..a16cea2ba980 100644 --- a/drivers/pps/kc.c +++ b/drivers/pps/kc.c | |||
@@ -113,10 +113,12 @@ void pps_kc_event(struct pps_device *pps, struct pps_event_time *ts, | |||
113 | int event) | 113 | int event) |
114 | { | 114 | { |
115 | unsigned long flags; | 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 | /* Pass some events to kernel consumer if activated */ | 119 | /* Pass some events to kernel consumer if activated */ |
118 | spin_lock_irqsave(&pps_kc_hardpps_lock, flags); | 120 | spin_lock_irqsave(&pps_kc_hardpps_lock, flags); |
119 | if (pps == pps_kc_hardpps_dev && event & pps_kc_hardpps_mode) | 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 | spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags); | 123 | spin_unlock_irqrestore(&pps_kc_hardpps_lock, flags); |
122 | } | 124 | } |
diff --git a/include/linux/timex.h b/include/linux/timex.h index 9d3f1a5b6178..39c25dbebfe8 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -152,7 +152,7 @@ extern unsigned long tick_nsec; /* SHIFTED_HZ period (nsec) */ | |||
152 | #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) | 152 | #define NTP_INTERVAL_LENGTH (NSEC_PER_SEC/NTP_INTERVAL_FREQ) |
153 | 153 | ||
154 | extern int do_adjtimex(struct timex *); | 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 | int read_current_timer(unsigned long *timer_val); | 157 | int read_current_timer(unsigned long *timer_val); |
158 | void ntp_notify_cmos_timer(void); | 158 | void ntp_notify_cmos_timer(void); |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index df68cb875248..bd4fa6271262 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -99,7 +99,7 @@ static time64_t ntp_next_leap_sec = TIME64_MAX; | |||
99 | static int pps_valid; /* signal watchdog counter */ | 99 | static int pps_valid; /* signal watchdog counter */ |
100 | static long pps_tf[3]; /* phase median filter */ | 100 | static long pps_tf[3]; /* phase median filter */ |
101 | static long pps_jitter; /* current jitter (ns) */ | 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 | static int pps_shift; /* current interval duration (s) (shift) */ | 103 | static int pps_shift; /* current interval duration (s) (shift) */ |
104 | static int pps_intcnt; /* interval counter */ | 104 | static int pps_intcnt; /* interval counter */ |
105 | static s64 pps_freq; /* frequency offset (scaled ns/s) */ | 105 | static s64 pps_freq; /* frequency offset (scaled ns/s) */ |
@@ -773,13 +773,13 @@ int __do_adjtimex(struct timex *txc, struct timespec64 *ts, s32 *time_tai) | |||
773 | * pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] | 773 | * pps_normtime.nsec has a range of ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] |
774 | * while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */ | 774 | * while timespec.tv_nsec has a range of [0, NSEC_PER_SEC) */ |
775 | struct pps_normtime { | 775 | struct pps_normtime { |
776 | __kernel_time_t sec; /* seconds */ | 776 | s64 sec; /* seconds */ |
777 | long nsec; /* nanoseconds */ | 777 | long nsec; /* nanoseconds */ |
778 | }; | 778 | }; |
779 | 779 | ||
780 | /* normalize the timestamp so that nsec is in the | 780 | /* normalize the timestamp so that nsec is in the |
781 | ( -NSEC_PER_SEC / 2, NSEC_PER_SEC / 2 ] interval */ | 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 | struct pps_normtime norm = { | 784 | struct pps_normtime norm = { |
785 | .sec = ts.tv_sec, | 785 | .sec = ts.tv_sec, |
@@ -861,7 +861,7 @@ static long hardpps_update_freq(struct pps_normtime freq_norm) | |||
861 | pps_errcnt++; | 861 | pps_errcnt++; |
862 | pps_dec_freq_interval(); | 862 | pps_dec_freq_interval(); |
863 | printk_deferred(KERN_ERR | 863 | printk_deferred(KERN_ERR |
864 | "hardpps: PPSERROR: interval too long - %ld s\n", | 864 | "hardpps: PPSERROR: interval too long - %lld s\n", |
865 | freq_norm.sec); | 865 | freq_norm.sec); |
866 | return 0; | 866 | return 0; |
867 | } | 867 | } |
@@ -948,7 +948,7 @@ static void hardpps_update_phase(long error) | |||
948 | * This code is based on David Mills's reference nanokernel | 948 | * This code is based on David Mills's reference nanokernel |
949 | * implementation. It was mostly rewritten but keeps the same idea. | 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 | struct pps_normtime pts_norm, freq_norm; | 953 | struct pps_normtime pts_norm, freq_norm; |
954 | 954 | ||
@@ -969,7 +969,7 @@ void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts) | |||
969 | } | 969 | } |
970 | 970 | ||
971 | /* ok, now we have a base for frequency calculation */ | 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 | /* check that the signal is in the range | 974 | /* check that the signal is in the range |
975 | * [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */ | 975 | * [1s - MAXFREQ us, 1s + MAXFREQ us], otherwise reject it */ |
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h index 65430504ca26..af924470eac0 100644 --- a/kernel/time/ntp_internal.h +++ b/kernel/time/ntp_internal.h | |||
@@ -9,5 +9,5 @@ extern ktime_t ntp_get_next_leap(void); | |||
9 | extern int second_overflow(unsigned long secs); | 9 | extern int second_overflow(unsigned long secs); |
10 | extern int ntp_validate_timex(struct timex *); | 10 | extern int ntp_validate_timex(struct timex *); |
11 | extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); | 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 | #endif /* _LINUX_NTP_INTERNAL_H */ | 13 | #endif /* _LINUX_NTP_INTERNAL_H */ |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 3739ac6aa473..177188b11a2e 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -2025,7 +2025,7 @@ int do_adjtimex(struct timex *txc) | |||
2025 | /** | 2025 | /** |
2026 | * hardpps() - Accessor function to NTP __hardpps function | 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 | unsigned long flags; | 2030 | unsigned long flags; |
2031 | 2031 | ||