Commit c7963487 authored by DengChao's avatar DengChao Committed by John Stultz

ntp: Fix second_overflow's input parameter type to be 64bits

The function "second_overflow" uses "unsign long"
as its input parameter type which will overflow after
year 2106 on 32bit systems.

Thus this patch replaces it with time64_t type.

While the 64-bit division is expensive, "next_ntp_leap_sec"
has been calculated already, so we can just re-use it in the
TIME_INS/DEL cases, allowing one expensive division per
leapsecond instead of re-doing the divsion once a second after
the leap flag has been set.
Signed-off-by: default avatarDengChao <chao.deng@linaro.org>
[jstultz: Tweaked commit message]
Signed-off-by: default avatarJohn Stultz <john.stultz@linaro.org>
parent 0af86465
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/rtc.h> #include <linux/rtc.h>
#include <linux/math64.h>
#include "ntp_internal.h" #include "ntp_internal.h"
#include "timekeeping_internal.h" #include "timekeeping_internal.h"
...@@ -394,10 +395,11 @@ ktime_t ntp_get_next_leap(void) ...@@ -394,10 +395,11 @@ ktime_t ntp_get_next_leap(void)
* *
* Also handles leap second processing, and returns leap offset * Also handles leap second processing, and returns leap offset
*/ */
int second_overflow(unsigned long secs) int second_overflow(time64_t secs)
{ {
s64 delta; s64 delta;
int leap = 0; int leap = 0;
s32 rem;
/* /*
* Leap second processing. If in leap-insert state at the end of the * Leap second processing. If in leap-insert state at the end of the
...@@ -408,19 +410,19 @@ int second_overflow(unsigned long secs) ...@@ -408,19 +410,19 @@ int second_overflow(unsigned long secs)
case TIME_OK: case TIME_OK:
if (time_status & STA_INS) { if (time_status & STA_INS) {
time_state = TIME_INS; time_state = TIME_INS;
ntp_next_leap_sec = secs + SECS_PER_DAY - div_s64_rem(secs, SECS_PER_DAY, &rem);
(secs % SECS_PER_DAY); ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
} else if (time_status & STA_DEL) { } else if (time_status & STA_DEL) {
time_state = TIME_DEL; time_state = TIME_DEL;
ntp_next_leap_sec = secs + SECS_PER_DAY - div_s64_rem(secs + 1, SECS_PER_DAY, &rem);
((secs+1) % SECS_PER_DAY); ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
} }
break; break;
case TIME_INS: case TIME_INS:
if (!(time_status & STA_INS)) { if (!(time_status & STA_INS)) {
ntp_next_leap_sec = TIME64_MAX; ntp_next_leap_sec = TIME64_MAX;
time_state = TIME_OK; time_state = TIME_OK;
} else if (secs % SECS_PER_DAY == 0) { } else if (secs == ntp_next_leap_sec) {
leap = -1; leap = -1;
time_state = TIME_OOP; time_state = TIME_OOP;
printk(KERN_NOTICE printk(KERN_NOTICE
...@@ -431,7 +433,7 @@ int second_overflow(unsigned long secs) ...@@ -431,7 +433,7 @@ int second_overflow(unsigned long secs)
if (!(time_status & STA_DEL)) { if (!(time_status & STA_DEL)) {
ntp_next_leap_sec = TIME64_MAX; ntp_next_leap_sec = TIME64_MAX;
time_state = TIME_OK; time_state = TIME_OK;
} else if ((secs + 1) % SECS_PER_DAY == 0) { } else if (secs == ntp_next_leap_sec) {
leap = 1; leap = 1;
ntp_next_leap_sec = TIME64_MAX; ntp_next_leap_sec = TIME64_MAX;
time_state = TIME_WAIT; time_state = TIME_WAIT;
......
...@@ -6,7 +6,7 @@ extern void ntp_clear(void); ...@@ -6,7 +6,7 @@ extern void ntp_clear(void);
/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */ /* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */
extern u64 ntp_tick_length(void); extern u64 ntp_tick_length(void);
extern ktime_t ntp_get_next_leap(void); extern ktime_t ntp_get_next_leap(void);
extern int second_overflow(unsigned long secs); extern int second_overflow(time64_t secs);
extern int ntp_validate_timex(struct timex *); extern int ntp_validate_timex(struct timex *);
extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
extern void __hardpps(const struct timespec64 *, const struct timespec64 *); extern void __hardpps(const struct timespec64 *, const struct timespec64 *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment