linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL][PATCH 0/4] Timekeeping queue for 4.17
@ 2018-03-09 18:42 John Stultz
  2018-03-09 18:42 ` [PATCH 1/4] timekeeping: Don't align frequency adjustments to ticks John Stultz
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: John Stultz @ 2018-03-09 18:42 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Alexandre Belloni, Arnd Bergmann, Benjamin Gaignard,
	Ingo Molnar, Miroslav Lichvar, Prarit Bhargava, Richard Cochran,
	Stephen Boyd, Thomas Gleixner, x86

Hey Thomas,
  Just wanted to send along my timekeeping queue for 4.17.
Its a bit short, and I want to apologize as I've not had much
time for maintanance and review work. I worry if my current
workload levels persist, I might need to downgrade my status
in the maintainers file, as I'm not particularly effective
these days. :/

Please let me know if you have any objections.

Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org


The following changes since commit 4a3928c6f8a53fa1aed28ccba227742486e8ddcb:

  Linux 4.16-rc3 (2018-02-25 18:50:41 -0800)

are available in the git repository at:

  https://git.linaro.org/people/john.stultz/linux.git fortglx/4.17/time

for you to fetch changes up to 54f2dcda2ac66a83588acbd6ef2dc98c01d8d3fb:

  x86: rtc: Stop using rtc deprecated functions (2018-03-09 10:35:13 -0800)

----------------------------------------------------------------

Arnd Bergmann (1):
  y2038: time: Introduce struct __kernel_old_timeval

Benjamin Gaignard (1):
  x86: rtc: Stop using rtc deprecated functions

Miroslav Lichvar (2):
  timekeeping: Don't align frequency adjustments to ticks
  timekeeping: Determine multiplier directly from NTP tick length

 arch/x86/kernel/rtc.c               |   6 +-
 include/linux/time32.h              |   1 +
 include/linux/timekeeper_internal.h |   2 +
 include/uapi/linux/time.h           |  12 +++
 kernel/time/time.c                  |  12 +++
 kernel/time/timekeeping.c           | 141 ++++++++++++------------------------
 6 files changed, 77 insertions(+), 97 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/4] timekeeping: Don't align frequency adjustments to ticks
  2018-03-09 18:42 [GIT PULL][PATCH 0/4] Timekeeping queue for 4.17 John Stultz
@ 2018-03-09 18:42 ` John Stultz
  2018-03-10  9:12   ` [tip:timers/core] timekeeping/ntp: Don't align NTP " tip-bot for Miroslav Lichvar
  2018-03-09 18:42 ` [PATCH 2/4] timekeeping: Determine multiplier directly from NTP tick length John Stultz
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 13+ messages in thread
From: John Stultz @ 2018-03-09 18:42 UTC (permalink / raw)
  To: lkml
  Cc: Miroslav Lichvar, Thomas Gleixner, Ingo Molnar, Richard Cochran,
	Prarit Bhargava, Stephen Boyd, John Stultz

From: Miroslav Lichvar <mlichvar@redhat.com>

When the timekeeping multiplier is changed, the NTP error is updated to
correct the clock for the delay between the tick and the update of the
clock. This error is corrected in later updates and the clock appears as
if the frequency was changed exactly on the tick.

Remove this correction to keep the point where the frequency is
effectively changed at the time of the update. This removes a major
source of the NTP error.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/timekeeping.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index cd03317..c1a0ac1 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1860,8 +1860,6 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 	 *	xtime_nsec_2 = xtime_nsec_1 - offset
 	 * Which simplfies to:
 	 *	xtime_nsec -= offset
-	 *
-	 * XXX - TODO: Doc ntp_error calculation.
 	 */
 	if ((mult_adj > 0) && (tk->tkr_mono.mult + mult_adj < mult_adj)) {
 		/* NTP adjustment caused clocksource mult overflow */
@@ -1872,7 +1870,6 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 	tk->tkr_mono.mult += mult_adj;
 	tk->xtime_interval += interval;
 	tk->tkr_mono.xtime_nsec -= offset;
-	tk->ntp_error -= (interval - offset) << tk->ntp_error_shift;
 }
 
 /*
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/4] timekeeping: Determine multiplier directly from NTP tick length
  2018-03-09 18:42 [GIT PULL][PATCH 0/4] Timekeeping queue for 4.17 John Stultz
  2018-03-09 18:42 ` [PATCH 1/4] timekeeping: Don't align frequency adjustments to ticks John Stultz
@ 2018-03-09 18:42 ` John Stultz
  2018-03-10  9:13   ` [tip:timers/core] timekeeping/ntp: Determine the " tip-bot for Miroslav Lichvar
  2018-03-09 18:42 ` [PATCH 3/4] y2038: time: Introduce struct __kernel_old_timeval John Stultz
  2018-03-09 18:42 ` [PATCH 4/4] x86: rtc: Stop using rtc deprecated functions John Stultz
  3 siblings, 1 reply; 13+ messages in thread
From: John Stultz @ 2018-03-09 18:42 UTC (permalink / raw)
  To: lkml
  Cc: Miroslav Lichvar, Thomas Gleixner, Ingo Molnar, Richard Cochran,
	Prarit Bhargava, Stephen Boyd, John Stultz

From: Miroslav Lichvar <mlichvar@redhat.com>

When the length of the NTP tick changes significantly, e.g. when an
NTP/PTP application is correcting the initial offset of the clock, a
large value may accumulate in the NTP error before the multiplier
converges to the correct value. It may then take a very long time (hours
or even days) before the error is corrected. This causes the clock to
have an unstable frequency offset, which has a negative impact on the
stability of synchronization with precise time sources (e.g. NTP/PTP
using hardware timestamping or the PTP KVM clock).

Use division to determine the correct multiplier directly from the NTP
tick length and replace the iterative approach. This removes the last
major source of the NTP error. The only remaining source is now limited
resolution of the multiplier, which is corrected by adding 1 to the
multiplier when the system clock is behind the NTP time.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 include/linux/timekeeper_internal.h |   2 +
 kernel/time/timekeeping.c           | 138 ++++++++++++------------------------
 2 files changed, 49 insertions(+), 91 deletions(-)

diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index d315c3d..7acb953 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -117,6 +117,8 @@ struct timekeeper {
 	s64			ntp_error;
 	u32			ntp_error_shift;
 	u32			ntp_err_mult;
+	/* Flag used to avoid updating NTP twice with same second */
+	u32			skip_second_overflow;
 #ifdef CONFIG_DEBUG_TIMEKEEPING
 	long			last_warning;
 	/*
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c1a0ac1..e1176012 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -332,6 +332,7 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
 	tk->tkr_mono.mult = clock->mult;
 	tk->tkr_raw.mult = clock->mult;
 	tk->ntp_err_mult = 0;
+	tk->skip_second_overflow = 0;
 }
 
 /* Timekeeper helper functions. */
@@ -1799,20 +1800,19 @@ device_initcall(timekeeping_init_ops);
  */
 static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 							 s64 offset,
-							 bool negative,
-							 int adj_scale)
+							 s32 mult_adj)
 {
 	s64 interval = tk->cycle_interval;
-	s32 mult_adj = 1;
 
-	if (negative) {
-		mult_adj = -mult_adj;
+	if (mult_adj == 0) {
+		return;
+	} else if (mult_adj == -1) {
 		interval = -interval;
-		offset  = -offset;
+		offset = -offset;
+	} else if (mult_adj != 1) {
+		interval *= mult_adj;
+		offset *= mult_adj;
 	}
-	mult_adj <<= adj_scale;
-	interval <<= adj_scale;
-	offset <<= adj_scale;
 
 	/*
 	 * So the following can be confusing.
@@ -1873,85 +1873,35 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 }
 
 /*
- * Calculate the multiplier adjustment needed to match the frequency
- * specified by NTP
+ * Adjust the timekeeper's multiplier to the correct frequency
+ * and also to reduce the accumulated error value.
  */
-static __always_inline void timekeeping_freqadjust(struct timekeeper *tk,
-							s64 offset)
+static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
 {
-	s64 interval = tk->cycle_interval;
-	s64 xinterval = tk->xtime_interval;
-	u32 base = tk->tkr_mono.clock->mult;
-	u32 max = tk->tkr_mono.clock->maxadj;
-	u32 cur_adj = tk->tkr_mono.mult;
-	s64 tick_error;
-	bool negative;
-	u32 adj_scale;
-
-	/* Remove any current error adj from freq calculation */
-	if (tk->ntp_err_mult)
-		xinterval -= tk->cycle_interval;
-
-	tk->ntp_tick = ntp_tick_length();
-
-	/* Calculate current error per tick */
-	tick_error = ntp_tick_length() >> tk->ntp_error_shift;
-	tick_error -= (xinterval + tk->xtime_remainder);
-
-	/* Don't worry about correcting it if its small */
-	if (likely((tick_error >= 0) && (tick_error <= interval)))
-		return;
-
-	/* preserve the direction of correction */
-	negative = (tick_error < 0);
+	u32 mult;
 
-	/* If any adjustment would pass the max, just return */
-	if (negative && (cur_adj - 1) <= (base - max))
-		return;
-	if (!negative && (cur_adj + 1) >= (base + max))
-		return;
 	/*
-	 * Sort out the magnitude of the correction, but
-	 * avoid making so large a correction that we go
-	 * over the max adjustment.
+	 * Determine the multiplier from the current NTP tick length.
+	 * Avoid expensive division when the tick length doesn't change.
 	 */
-	adj_scale = 0;
-	tick_error = abs(tick_error);
-	while (tick_error > interval) {
-		u32 adj = 1 << (adj_scale + 1);
-
-		/* Check if adjustment gets us within 1 unit from the max */
-		if (negative && (cur_adj - adj) <= (base - max))
-			break;
-		if (!negative && (cur_adj + adj) >= (base + max))
-			break;
-
-		adj_scale++;
-		tick_error >>= 1;
+	if (likely(tk->ntp_tick == ntp_tick_length())) {
+		mult = tk->tkr_mono.mult - tk->ntp_err_mult;
+	} else {
+		tk->ntp_tick = ntp_tick_length();
+		mult = div64_u64((tk->ntp_tick >> tk->ntp_error_shift) -
+				 tk->xtime_remainder, tk->cycle_interval);
 	}
 
-	/* scale the corrections */
-	timekeeping_apply_adjustment(tk, offset, negative, adj_scale);
-}
+	/*
+	 * If the clock is behind the NTP time, increase the multiplier by 1
+	 * to catch up with it. If it's ahead and there was a remainder in the
+	 * tick division, the clock will slow down. Otherwise it will stay
+	 * ahead until the tick length changes to a non-divisible value.
+	 */
+	tk->ntp_err_mult = tk->ntp_error > 0 ? 1 : 0;
+	mult += tk->ntp_err_mult;
 
-/*
- * Adjust the timekeeper's multiplier to the correct frequency
- * and also to reduce the accumulated error value.
- */
-static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
-{
-	/* Correct for the current frequency error */
-	timekeeping_freqadjust(tk, offset);
-
-	/* Next make a small adjustment to fix any cumulative error */
-	if (!tk->ntp_err_mult && (tk->ntp_error > 0)) {
-		tk->ntp_err_mult = 1;
-		timekeeping_apply_adjustment(tk, offset, 0, 0);
-	} else if (tk->ntp_err_mult && (tk->ntp_error <= 0)) {
-		/* Undo any existing error adjustment */
-		timekeeping_apply_adjustment(tk, offset, 1, 0);
-		tk->ntp_err_mult = 0;
-	}
+	timekeeping_apply_adjustment(tk, offset, mult - tk->tkr_mono.mult);
 
 	if (unlikely(tk->tkr_mono.clock->maxadj &&
 		(abs(tk->tkr_mono.mult - tk->tkr_mono.clock->mult)
@@ -1968,18 +1918,15 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
 	 * in the code above, its possible the required corrective factor to
 	 * xtime_nsec could cause it to underflow.
 	 *
-	 * Now, since we already accumulated the second, cannot simply roll
-	 * the accumulated second back, since the NTP subsystem has been
-	 * notified via second_overflow. So instead we push xtime_nsec forward
-	 * by the amount we underflowed, and add that amount into the error.
-	 *
-	 * We'll correct this error next time through this function, when
-	 * xtime_nsec is not as small.
+	 * Now, since we have already accumulated the second and the NTP
+	 * subsystem has been notified via second_overflow(), we need to skip
+	 * the next update.
 	 */
 	if (unlikely((s64)tk->tkr_mono.xtime_nsec < 0)) {
-		s64 neg = -(s64)tk->tkr_mono.xtime_nsec;
-		tk->tkr_mono.xtime_nsec = 0;
-		tk->ntp_error += neg << tk->ntp_error_shift;
+		tk->tkr_mono.xtime_nsec += (u64)NSEC_PER_SEC <<
+							tk->tkr_mono.shift;
+		tk->xtime_sec--;
+		tk->skip_second_overflow = 1;
 	}
 }
 
@@ -2002,6 +1949,15 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
 		tk->tkr_mono.xtime_nsec -= nsecps;
 		tk->xtime_sec++;
 
+		/*
+		 * Skip NTP update if this second was accumulated before,
+		 * i.e. xtime_nsec underflowed in timekeeping_adjust()
+		 */
+		if (unlikely(tk->skip_second_overflow)) {
+			tk->skip_second_overflow = 0;
+			continue;
+		}
+
 		/* Figure out if its a leap sec and apply if needed */
 		leap = second_overflow(tk->xtime_sec);
 		if (unlikely(leap)) {
@@ -2118,7 +2074,7 @@ void update_wall_time(void)
 			shift--;
 	}
 
-	/* correct the clock when NTP error is too big */
+	/* Adjust the multiplier to correct NTP error */
 	timekeeping_adjust(tk, offset);
 
 	/*
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/4] y2038: time: Introduce struct __kernel_old_timeval
  2018-03-09 18:42 [GIT PULL][PATCH 0/4] Timekeeping queue for 4.17 John Stultz
  2018-03-09 18:42 ` [PATCH 1/4] timekeeping: Don't align frequency adjustments to ticks John Stultz
  2018-03-09 18:42 ` [PATCH 2/4] timekeeping: Determine multiplier directly from NTP tick length John Stultz
@ 2018-03-09 18:42 ` John Stultz
  2018-03-10  8:11   ` Ingo Molnar
  2018-03-09 18:42 ` [PATCH 4/4] x86: rtc: Stop using rtc deprecated functions John Stultz
  3 siblings, 1 reply; 13+ messages in thread
From: John Stultz @ 2018-03-09 18:42 UTC (permalink / raw)
  To: lkml
  Cc: Arnd Bergmann, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, John Stultz

From: Arnd Bergmann <arnd@arndb.de>

Dealing with 'struct timeval' users in the y2038 series is a bit tricky:

We have two definitions of timeval that are visible to user space,
one comes from glibc (or some other C library), the other comes from
linux/time.h. The kernel copy is what we want to be used for a number of
structures defined by the kernel itself, e.g. elf_prstatus (used it core
dumps), sysinfo and rusage (used in system calls).  These generally tend
to be used for passing time intervals rather than absolute (epoch-based)
times, so they do not suffer from the y2038 overflow. Some of them
could be changed to use 64-bit timestamps by creating new system calls,
others like the core files cannot easily be changed.

An application using these interfaces likely also uses gettimeofday()
or other interfaces that use absolute times, and pass 'struct timeval'
pointers directly into kernel interfaces, so glibc must redefine their
timeval based on a 64-bit time_t when they introduce their y2038-safe
interfaces.

The only reasonable way forward I see is to remove the 'timeval'
definition from the kernel's uapi headers, and change the interfaces
that we do not want to (or cannot) duplicate for 64-bit times to use a
new __kernel_old_timeval definition instead. This type should be avoided
for all new interfaces (those can use 64-bit nanoseconds, or the 64-bit
version of timespec instead), and should be used with great care when
converting existing interfaces from timeval, to be sure they don't suffer
from the y2038 overflow, and only with consensus for the particular user
that using __kernel_old_timeval is better than moving to a 64-bit based
interface. The structure name is intentionally chosen to not conflict
with user space types, and to be ugly enough to discourage its use.

Note that ioctl based interfaces that pass a bare 'timeval' pointer
cannot change to '__kernel_old_timeval' because the user space source
code refers to 'timeval' instead, and we don't want to modify the user
space sources if possible. However, any application that relies on a
structure to contain an embedded 'timeval' (e.g. by passing a pointer
to the member into a function call that expects a timeval pointer) is
broken when that structure gets converted to __kernel_old_timeval. I
don't see any way around that, and we have to rely on the compiler to
produce a warning or compile failure that will alert users when they
recompile their sources against a new libc.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 include/linux/time32.h    |  1 +
 include/uapi/linux/time.h | 12 ++++++++++++
 kernel/time/time.c        | 12 ++++++++++++
 3 files changed, 25 insertions(+)

diff --git a/include/linux/time32.h b/include/linux/time32.h
index 65b1de2..3febcaf 100644
--- a/include/linux/time32.h
+++ b/include/linux/time32.h
@@ -217,5 +217,6 @@ static inline s64 timeval_to_ns(const struct timeval *tv)
  * Returns the timeval representation of the nsec parameter.
  */
 extern struct timeval ns_to_timeval(const s64 nsec);
+extern struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec);
 
 #endif
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index 53f8dd8..888da62 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -43,6 +43,18 @@ struct itimerval {
 };
 
 /*
+ * legacy timeval structure, only embedded in structures that
+ * traditionally used 'timeval' to pass time intervals (not absolute
+ * times). Do not add new users. If user space fails to compile
+ * here, this is probably because it is not y2038 safe and needs to
+ * be changed to use another interface.
+ */
+struct __kernel_old_timeval {
+	__kernel_long_t tv_sec;			/* seconds */
+	__kernel_long_t tv_usec;		/* seconds */
+};
+
+/*
  * The IDs of the various system clocks (for POSIX.1b interval timers):
  */
 #define CLOCK_REALTIME			0
diff --git a/kernel/time/time.c b/kernel/time/time.c
index bd4e6c7..cbb3c71 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -488,6 +488,18 @@ struct timeval ns_to_timeval(const s64 nsec)
 }
 EXPORT_SYMBOL(ns_to_timeval);
 
+struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec)
+{
+	struct timespec64 ts = ns_to_timespec64(nsec);
+	struct __kernel_old_timeval tv;
+
+	tv.tv_sec = ts.tv_sec;
+	tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
+
+	return tv;
+}
+EXPORT_SYMBOL(ns_to_kernel_old_timeval);
+
 /**
  * set_normalized_timespec - set timespec sec and nsec parts and normalize
  *
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/4] x86: rtc: Stop using rtc deprecated functions
  2018-03-09 18:42 [GIT PULL][PATCH 0/4] Timekeeping queue for 4.17 John Stultz
                   ` (2 preceding siblings ...)
  2018-03-09 18:42 ` [PATCH 3/4] y2038: time: Introduce struct __kernel_old_timeval John Stultz
@ 2018-03-09 18:42 ` John Stultz
  2018-03-15  8:52   ` [tip:x86/cleanups] x86/rtc: Stop using " tip-bot for Benjamin Gaignard
  3 siblings, 1 reply; 13+ messages in thread
From: John Stultz @ 2018-03-09 18:42 UTC (permalink / raw)
  To: lkml
  Cc: Benjamin Gaignard, Arnd Bergmann, Thomas Gleixner, Ingo Molnar,
	x86, Miroslav Lichvar, Richard Cochran, Prarit Bhargava,
	Stephen Boyd, Alexandre Belloni, John Stultz

From: Benjamin Gaignard <benjamin.gaignard@linaro.org>

rtc_time_to_tm() and rtc_tm_to_time() are deprecated because they
rely on 32bits variables and that will make rtc break in y2038/2016.
Stop using those two functions to safer 64bits ones.

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: x86@kernel.org
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/x86/kernel/rtc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 69ac9cb..f7b82ed 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -41,11 +41,11 @@ EXPORT_SYMBOL(rtc_lock);
  */
 int mach_set_rtc_mmss(const struct timespec *now)
 {
-	unsigned long nowtime = now->tv_sec;
+	unsigned long long nowtime = now->tv_sec;
 	struct rtc_time tm;
 	int retval = 0;
 
-	rtc_time_to_tm(nowtime, &tm);
+	rtc_time64_to_tm(nowtime, &tm);
 	if (!rtc_valid_tm(&tm)) {
 		retval = mc146818_set_time(&tm);
 		if (retval)
@@ -53,7 +53,7 @@ int mach_set_rtc_mmss(const struct timespec *now)
 			       __func__, retval);
 	} else {
 		printk(KERN_ERR
-		       "%s: Invalid RTC value: write of %lx to RTC failed\n",
+		       "%s: Invalid RTC value: write of %llx to RTC failed\n",
 			__func__, nowtime);
 		retval = -EINVAL;
 	}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/4] y2038: time: Introduce struct __kernel_old_timeval
  2018-03-09 18:42 ` [PATCH 3/4] y2038: time: Introduce struct __kernel_old_timeval John Stultz
@ 2018-03-10  8:11   ` Ingo Molnar
  2018-03-14 22:02     ` Arnd Bergmann
  0 siblings, 1 reply; 13+ messages in thread
From: Ingo Molnar @ 2018-03-10  8:11 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Arnd Bergmann, Thomas Gleixner, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd


> +extern struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec);

Generally there's no need to mark arguments with arithmethic types as const, as 
they are never modified in the calling scope.

> + * legacy timeval structure, only embedded in structures that
> + * traditionally used 'timeval' to pass time intervals (not absolute
> + * times). Do not add new users. If user space fails to compile
> + * here, this is probably because it is not y2038 safe and needs to
> + * be changed to use another interface.
> + */
> +struct __kernel_old_timeval {
> +	__kernel_long_t tv_sec;			/* seconds */
> +	__kernel_long_t tv_usec;		/* seconds */

s/seconds/microseconds

> +struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec)
> +{
> +	struct timespec64 ts = ns_to_timespec64(nsec);
> +	struct __kernel_old_timeval tv;
> +
> +	tv.tv_sec = ts.tv_sec;
> +	tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;

Is ts.tv_nsec guaranteed to never have bits set in the high 32 bits?

In any case, the space before the type cast is a bit confusing to me, I think it 
should be written as:

	tv.tv_usec = (suseconds_t)ts.tv_nsec / 1000;

To better show was the higher precedence of the cast is going to result in.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip:timers/core] timekeeping/ntp: Don't align NTP frequency adjustments to ticks
  2018-03-09 18:42 ` [PATCH 1/4] timekeeping: Don't align frequency adjustments to ticks John Stultz
@ 2018-03-10  9:12   ` tip-bot for Miroslav Lichvar
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Miroslav Lichvar @ 2018-03-10  9:12 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: prarit, hpa, stephen.boyd, torvalds, richardcochran, mlichvar,
	tglx, peterz, john.stultz, linux-kernel, mingo

Commit-ID:  c2cda2a5bda9f1369c9d1ab54a20571c13cf2743
Gitweb:     https://git.kernel.org/tip/c2cda2a5bda9f1369c9d1ab54a20571c13cf2743
Author:     Miroslav Lichvar <mlichvar@redhat.com>
AuthorDate: Fri, 9 Mar 2018 10:42:47 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sat, 10 Mar 2018 09:12:41 +0100

timekeeping/ntp: Don't align NTP frequency adjustments to ticks

When the timekeeping multiplier is changed, the NTP error is updated to
correct the clock for the delay between the tick and the update of the
clock. This error is corrected in later updates and the clock appears as
if the frequency was changed exactly on the tick.

Remove this correction to keep the point where the frequency is
effectively changed at the time of the update. This removes a major
source of the NTP error.

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1520620971-9567-2-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/time/timekeeping.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index cd03317e7b57..c1a0ac17336e 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1860,8 +1860,6 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 	 *	xtime_nsec_2 = xtime_nsec_1 - offset
 	 * Which simplfies to:
 	 *	xtime_nsec -= offset
-	 *
-	 * XXX - TODO: Doc ntp_error calculation.
 	 */
 	if ((mult_adj > 0) && (tk->tkr_mono.mult + mult_adj < mult_adj)) {
 		/* NTP adjustment caused clocksource mult overflow */
@@ -1872,7 +1870,6 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 	tk->tkr_mono.mult += mult_adj;
 	tk->xtime_interval += interval;
 	tk->tkr_mono.xtime_nsec -= offset;
-	tk->ntp_error -= (interval - offset) << tk->ntp_error_shift;
 }
 
 /*

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [tip:timers/core] timekeeping/ntp: Determine the multiplier directly from NTP tick length
  2018-03-09 18:42 ` [PATCH 2/4] timekeeping: Determine multiplier directly from NTP tick length John Stultz
@ 2018-03-10  9:13   ` tip-bot for Miroslav Lichvar
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Miroslav Lichvar @ 2018-03-10  9:13 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, john.stultz, linux-kernel, hpa, mlichvar, torvalds,
	richardcochran, prarit, tglx, stephen.boyd, mingo

Commit-ID:  78b98e3c5a66d569a53b8f57b6a698f912794a43
Gitweb:     https://git.kernel.org/tip/78b98e3c5a66d569a53b8f57b6a698f912794a43
Author:     Miroslav Lichvar <mlichvar@redhat.com>
AuthorDate: Fri, 9 Mar 2018 10:42:48 -0800
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sat, 10 Mar 2018 09:12:41 +0100

timekeeping/ntp: Determine the multiplier directly from NTP tick length

When the length of the NTP tick changes significantly, e.g. when an
NTP/PTP application is correcting the initial offset of the clock, a
large value may accumulate in the NTP error before the multiplier
converges to the correct value. It may then take a very long time (hours
or even days) before the error is corrected. This causes the clock to
have an unstable frequency offset, which has a negative impact on the
stability of synchronization with precise time sources (e.g. NTP/PTP
using hardware timestamping or the PTP KVM clock).

Use division to determine the correct multiplier directly from the NTP
tick length and replace the iterative approach. This removes the last
major source of the NTP error. The only remaining source is now limited
resolution of the multiplier, which is corrected by adding 1 to the
multiplier when the system clock is behind the NTP time.

Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1520620971-9567-3-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/timekeeper_internal.h |   2 +
 kernel/time/timekeeping.c           | 138 ++++++++++++------------------------
 2 files changed, 49 insertions(+), 91 deletions(-)

diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index d315c3d6725c..7acb953298a7 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -117,6 +117,8 @@ struct timekeeper {
 	s64			ntp_error;
 	u32			ntp_error_shift;
 	u32			ntp_err_mult;
+	/* Flag used to avoid updating NTP twice with same second */
+	u32			skip_second_overflow;
 #ifdef CONFIG_DEBUG_TIMEKEEPING
 	long			last_warning;
 	/*
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c1a0ac17336e..e11760121cb2 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -332,6 +332,7 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
 	tk->tkr_mono.mult = clock->mult;
 	tk->tkr_raw.mult = clock->mult;
 	tk->ntp_err_mult = 0;
+	tk->skip_second_overflow = 0;
 }
 
 /* Timekeeper helper functions. */
@@ -1799,20 +1800,19 @@ device_initcall(timekeeping_init_ops);
  */
 static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 							 s64 offset,
-							 bool negative,
-							 int adj_scale)
+							 s32 mult_adj)
 {
 	s64 interval = tk->cycle_interval;
-	s32 mult_adj = 1;
 
-	if (negative) {
-		mult_adj = -mult_adj;
+	if (mult_adj == 0) {
+		return;
+	} else if (mult_adj == -1) {
 		interval = -interval;
-		offset  = -offset;
+		offset = -offset;
+	} else if (mult_adj != 1) {
+		interval *= mult_adj;
+		offset *= mult_adj;
 	}
-	mult_adj <<= adj_scale;
-	interval <<= adj_scale;
-	offset <<= adj_scale;
 
 	/*
 	 * So the following can be confusing.
@@ -1873,85 +1873,35 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 }
 
 /*
- * Calculate the multiplier adjustment needed to match the frequency
- * specified by NTP
+ * Adjust the timekeeper's multiplier to the correct frequency
+ * and also to reduce the accumulated error value.
  */
-static __always_inline void timekeeping_freqadjust(struct timekeeper *tk,
-							s64 offset)
+static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
 {
-	s64 interval = tk->cycle_interval;
-	s64 xinterval = tk->xtime_interval;
-	u32 base = tk->tkr_mono.clock->mult;
-	u32 max = tk->tkr_mono.clock->maxadj;
-	u32 cur_adj = tk->tkr_mono.mult;
-	s64 tick_error;
-	bool negative;
-	u32 adj_scale;
-
-	/* Remove any current error adj from freq calculation */
-	if (tk->ntp_err_mult)
-		xinterval -= tk->cycle_interval;
-
-	tk->ntp_tick = ntp_tick_length();
-
-	/* Calculate current error per tick */
-	tick_error = ntp_tick_length() >> tk->ntp_error_shift;
-	tick_error -= (xinterval + tk->xtime_remainder);
-
-	/* Don't worry about correcting it if its small */
-	if (likely((tick_error >= 0) && (tick_error <= interval)))
-		return;
-
-	/* preserve the direction of correction */
-	negative = (tick_error < 0);
+	u32 mult;
 
-	/* If any adjustment would pass the max, just return */
-	if (negative && (cur_adj - 1) <= (base - max))
-		return;
-	if (!negative && (cur_adj + 1) >= (base + max))
-		return;
 	/*
-	 * Sort out the magnitude of the correction, but
-	 * avoid making so large a correction that we go
-	 * over the max adjustment.
+	 * Determine the multiplier from the current NTP tick length.
+	 * Avoid expensive division when the tick length doesn't change.
 	 */
-	adj_scale = 0;
-	tick_error = abs(tick_error);
-	while (tick_error > interval) {
-		u32 adj = 1 << (adj_scale + 1);
-
-		/* Check if adjustment gets us within 1 unit from the max */
-		if (negative && (cur_adj - adj) <= (base - max))
-			break;
-		if (!negative && (cur_adj + adj) >= (base + max))
-			break;
-
-		adj_scale++;
-		tick_error >>= 1;
+	if (likely(tk->ntp_tick == ntp_tick_length())) {
+		mult = tk->tkr_mono.mult - tk->ntp_err_mult;
+	} else {
+		tk->ntp_tick = ntp_tick_length();
+		mult = div64_u64((tk->ntp_tick >> tk->ntp_error_shift) -
+				 tk->xtime_remainder, tk->cycle_interval);
 	}
 
-	/* scale the corrections */
-	timekeeping_apply_adjustment(tk, offset, negative, adj_scale);
-}
+	/*
+	 * If the clock is behind the NTP time, increase the multiplier by 1
+	 * to catch up with it. If it's ahead and there was a remainder in the
+	 * tick division, the clock will slow down. Otherwise it will stay
+	 * ahead until the tick length changes to a non-divisible value.
+	 */
+	tk->ntp_err_mult = tk->ntp_error > 0 ? 1 : 0;
+	mult += tk->ntp_err_mult;
 
-/*
- * Adjust the timekeeper's multiplier to the correct frequency
- * and also to reduce the accumulated error value.
- */
-static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
-{
-	/* Correct for the current frequency error */
-	timekeeping_freqadjust(tk, offset);
-
-	/* Next make a small adjustment to fix any cumulative error */
-	if (!tk->ntp_err_mult && (tk->ntp_error > 0)) {
-		tk->ntp_err_mult = 1;
-		timekeeping_apply_adjustment(tk, offset, 0, 0);
-	} else if (tk->ntp_err_mult && (tk->ntp_error <= 0)) {
-		/* Undo any existing error adjustment */
-		timekeeping_apply_adjustment(tk, offset, 1, 0);
-		tk->ntp_err_mult = 0;
-	}
+	timekeeping_apply_adjustment(tk, offset, mult - tk->tkr_mono.mult);
 
 	if (unlikely(tk->tkr_mono.clock->maxadj &&
 		(abs(tk->tkr_mono.mult - tk->tkr_mono.clock->mult)
@@ -1968,18 +1918,15 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
 	 * in the code above, its possible the required corrective factor to
 	 * xtime_nsec could cause it to underflow.
 	 *
-	 * Now, since we already accumulated the second, cannot simply roll
-	 * the accumulated second back, since the NTP subsystem has been
-	 * notified via second_overflow. So instead we push xtime_nsec forward
-	 * by the amount we underflowed, and add that amount into the error.
-	 *
-	 * We'll correct this error next time through this function, when
-	 * xtime_nsec is not as small.
+	 * Now, since we have already accumulated the second and the NTP
+	 * subsystem has been notified via second_overflow(), we need to skip
+	 * the next update.
 	 */
 	if (unlikely((s64)tk->tkr_mono.xtime_nsec < 0)) {
-		s64 neg = -(s64)tk->tkr_mono.xtime_nsec;
-		tk->tkr_mono.xtime_nsec = 0;
-		tk->ntp_error += neg << tk->ntp_error_shift;
+		tk->tkr_mono.xtime_nsec += (u64)NSEC_PER_SEC <<
+							tk->tkr_mono.shift;
+		tk->xtime_sec--;
+		tk->skip_second_overflow = 1;
 	}
 }
 
@@ -2002,6 +1949,15 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
 		tk->tkr_mono.xtime_nsec -= nsecps;
 		tk->xtime_sec++;
 
+		/*
+		 * Skip NTP update if this second was accumulated before,
+		 * i.e. xtime_nsec underflowed in timekeeping_adjust()
+		 */
+		if (unlikely(tk->skip_second_overflow)) {
+			tk->skip_second_overflow = 0;
+			continue;
+		}
+
 		/* Figure out if its a leap sec and apply if needed */
 		leap = second_overflow(tk->xtime_sec);
 		if (unlikely(leap)) {
@@ -2118,7 +2074,7 @@ void update_wall_time(void)
 			shift--;
 	}
 
-	/* correct the clock when NTP error is too big */
+	/* Adjust the multiplier to correct NTP error */
 	timekeeping_adjust(tk, offset);
 
 	/*

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/4] y2038: time: Introduce struct __kernel_old_timeval
  2018-03-10  8:11   ` Ingo Molnar
@ 2018-03-14 22:02     ` Arnd Bergmann
  2018-03-14 22:04       ` [PATCH] [v2] y2038: introduce " Arnd Bergmann
  0 siblings, 1 reply; 13+ messages in thread
From: Arnd Bergmann @ 2018-03-14 22:02 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: John Stultz, lkml, Thomas Gleixner, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd

On Sat, Mar 10, 2018 at 9:11 AM, Ingo Molnar <mingo@kernel.org> wrote:
>
>> +extern struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec);
>
> Generally there's no need to mark arguments with arithmethic types as const, as
> they are never modified in the calling scope.

Sure. Here I just copied from the neighboring line, but that's an obvious
change.

>> + * legacy timeval structure, only embedded in structures that
>> + * traditionally used 'timeval' to pass time intervals (not absolute
>> + * times). Do not add new users. If user space fails to compile
>> + * here, this is probably because it is not y2038 safe and needs to
>> + * be changed to use another interface.
>> + */
>> +struct __kernel_old_timeval {
>> +     __kernel_long_t tv_sec;                 /* seconds */
>> +     __kernel_long_t tv_usec;                /* seconds */
>
> s/seconds/microseconds

Right.

>> +struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec)
>> +{
>> +     struct timespec64 ts = ns_to_timespec64(nsec);
>> +     struct __kernel_old_timeval tv;
>> +
>> +     tv.tv_sec = ts.tv_sec;
>> +     tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
>
> Is ts.tv_nsec guaranteed to never have bits set in the high 32 bits?

Yes, ns_to_timespec64() produces a valid timespec64 structure.

> In any case, the space before the type cast is a bit confusing to me, I think it
> should be written as:
>
>         tv.tv_usec = (suseconds_t)ts.tv_nsec / 1000;
>
> To better show was the higher precedence of the cast is going to result in.

Sure.

Thanks for taking a look, I'll send an updated version.

       Arnd

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] [v2] y2038: introduce struct __kernel_old_timeval
  2018-03-14 22:02     ` Arnd Bergmann
@ 2018-03-14 22:04       ` Arnd Bergmann
  2018-03-15  8:44         ` Thomas Gleixner
  0 siblings, 1 reply; 13+ messages in thread
From: Arnd Bergmann @ 2018-03-14 22:04 UTC (permalink / raw)
  To: lkml
  Cc: Ingo Molnar, John Stultz, Thomas Gleixner, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, Arnd Bergmann,
	Deepa Dinamani

Dealing with 'struct timeval' users in the y2038 series is a bit tricky:

We have two definitions of timeval that are visible to user space,
one comes from glibc (or some other C library), the other comes from
linux/time.h. The kernel copy is what we want to be used for a number of
structures defined by the kernel itself, e.g. elf_prstatus (used it core
dumps), sysinfo and rusage (used in system calls).  These generally tend
to be used for passing time intervals rather than absolute (epoch-based)
times, so they do not suffer from the y2038 overflow. Some of them
could be changed to use 64-bit timestamps by creating new system calls,
others like the core files cannot easily be changed.

An application using these interfaces likely also uses gettimeofday()
or other interfaces that use absolute times, and pass 'struct timeval'
pointers directly into kernel interfaces, so glibc must redefine their
timeval based on a 64-bit time_t when they introduce their y2038-safe
interfaces.

The only reasonable way forward I see is to remove the 'timeval'
definion from the kernel's uapi headers, and change the interfaces that
we do not want to (or cannot) duplicate for 64-bit times to use a new
__kernel_old_timeval definition instead. This type should be avoided
for all new interfaces (those can use 64-bit nanoseconds, or the 64-bit
version of timespec instead), and should be used with great care when
converting existing interfaces from timeval, to be sure they don't suffer
from the y2038 overflow, and only with consensus for the particular user
that using __kernel_old_timeval is better than moving to a 64-bit based
interface. The structure name is intentionally chosen to not conflict
with user space types, and to be ugly enough to discourage its use.

Note that ioctl based interfaces that pass a bare 'timeval' pointer
cannot change to '__kernel_old_timeval' because the user space source
code refers to 'timeval' instead, and we don't want to modify the user
space sources if possible. However, any application that relies on a
structure to contain an embedded 'timeval' (e.g. by passing a pointer
to the member into a function call that expects a timeval pointer) is
broken when that structure gets converted to __kernel_old_timeval. I
don't see any way around that, and we have to rely on the compiler to
produce a warning or compile failure that will alert users when they
recompile their sources against a new libc.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2: update for Ingo's comments
---
 include/linux/time32.h    |  1 +
 include/uapi/linux/time.h | 12 ++++++++++++
 kernel/time/time.c        | 12 ++++++++++++
 3 files changed, 25 insertions(+)

diff --git a/include/linux/time32.h b/include/linux/time32.h
index 100411c979be..0b14f936100a 100644
--- a/include/linux/time32.h
+++ b/include/linux/time32.h
@@ -205,5 +205,6 @@ static inline s64 timeval_to_ns(const struct timeval *tv)
  * Returns the timeval representation of the nsec parameter.
  */
 extern struct timeval ns_to_timeval(const s64 nsec);
+extern struct __kernel_old_timeval ns_to_kernel_old_timeval(s64 nsec);
 
 #endif
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index 4ed5bd3a3145..44c994c8755e 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -50,6 +50,18 @@ struct __kernel_timespec {
 #endif
 
 /*
+ * legacy timeval structure, only embedded in structures that
+ * traditionally used 'timeval' to pass time intervals (not absolute
+ * times). Do not add new users. If user space fails to compile
+ * here, this is probably because it is not y2038 safe and needs to
+ * be changed to use another interface.
+ */
+struct __kernel_old_timeval {
+	__kernel_long_t tv_sec;			/* seconds */
+	__kernel_long_t tv_usec;		/* microseconds */
+};
+
+/*
  * The IDs of the various system clocks (for POSIX.1b interval timers):
  */
 #define CLOCK_REALTIME			0
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 5db8f15ec056..6fa99213fc72 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -486,6 +486,18 @@ struct timeval ns_to_timeval(const s64 nsec)
 }
 EXPORT_SYMBOL(ns_to_timeval);
 
+struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec)
+{
+	struct timespec64 ts = ns_to_timespec64(nsec);
+	struct __kernel_old_timeval tv;
+
+	tv.tv_sec = ts.tv_sec;
+	tv.tv_usec = (suseconds_t)ts.tv_nsec / 1000;
+
+	return tv;
+}
+EXPORT_SYMBOL(ns_to_kernel_old_timeval);
+
 /**
  * set_normalized_timespec - set timespec sec and nsec parts and normalize
  *
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] [v2] y2038: introduce struct __kernel_old_timeval
  2018-03-14 22:04       ` [PATCH] [v2] y2038: introduce " Arnd Bergmann
@ 2018-03-15  8:44         ` Thomas Gleixner
  2018-03-15 15:46           ` Arnd Bergmann
  0 siblings, 1 reply; 13+ messages in thread
From: Thomas Gleixner @ 2018-03-15  8:44 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: lkml, Ingo Molnar, John Stultz, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, Deepa Dinamani

On Wed, 14 Mar 2018, Arnd Bergmann wrote:
>  
>  /*
> + * legacy timeval structure, only embedded in structures that
> + * traditionally used 'timeval' to pass time intervals (not absolute
> + * times). Do not add new users. If user space fails to compile
> + * here, this is probably because it is not y2038 safe and needs to
> + * be changed to use another interface.
> + */
> +struct __kernel_old_timeval {
> +	__kernel_long_t tv_sec;			/* seconds */
> +	__kernel_long_t tv_usec;		/* microseconds */

Please don't use these horrible tail comments. If you want to document the
obvious, then please use proper kernel doc.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [tip:x86/cleanups] x86/rtc: Stop using deprecated functions
  2018-03-09 18:42 ` [PATCH 4/4] x86: rtc: Stop using rtc deprecated functions John Stultz
@ 2018-03-15  8:52   ` tip-bot for Benjamin Gaignard
  0 siblings, 0 replies; 13+ messages in thread
From: tip-bot for Benjamin Gaignard @ 2018-03-15  8:52 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, arnd, mingo, mlichvar, linux-kernel, prarit,
	richardcochran, benjamin.gaignard, alexandre.belloni,
	stephen.boyd, john.stultz, hpa

Commit-ID:  13cc36d76bc4f5a9801ae32630bc8240ba0cc522
Gitweb:     https://git.kernel.org/tip/13cc36d76bc4f5a9801ae32630bc8240ba0cc522
Author:     Benjamin Gaignard <benjamin.gaignard@linaro.org>
AuthorDate: Fri, 9 Mar 2018 10:42:50 -0800
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 15 Mar 2018 09:47:24 +0100

x86/rtc: Stop using deprecated functions

rtc_time_to_tm() and rtc_tm_to_time() are deprecated because they
rely on 32bits variables and that will make rtc break in y2038/2016.

Use the proper y2038 safe functions.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Link: https://lkml.kernel.org/r/1520620971-9567-5-git-send-email-john.stultz@linaro.org

---
 arch/x86/kernel/rtc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 69ac9cb9cac6..f7b82ed7b5b5 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -41,11 +41,11 @@ EXPORT_SYMBOL(rtc_lock);
  */
 int mach_set_rtc_mmss(const struct timespec *now)
 {
-	unsigned long nowtime = now->tv_sec;
+	unsigned long long nowtime = now->tv_sec;
 	struct rtc_time tm;
 	int retval = 0;
 
-	rtc_time_to_tm(nowtime, &tm);
+	rtc_time64_to_tm(nowtime, &tm);
 	if (!rtc_valid_tm(&tm)) {
 		retval = mc146818_set_time(&tm);
 		if (retval)
@@ -53,7 +53,7 @@ int mach_set_rtc_mmss(const struct timespec *now)
 			       __func__, retval);
 	} else {
 		printk(KERN_ERR
-		       "%s: Invalid RTC value: write of %lx to RTC failed\n",
+		       "%s: Invalid RTC value: write of %llx to RTC failed\n",
 			__func__, nowtime);
 		retval = -EINVAL;
 	}

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] [v2] y2038: introduce struct __kernel_old_timeval
  2018-03-15  8:44         ` Thomas Gleixner
@ 2018-03-15 15:46           ` Arnd Bergmann
  0 siblings, 0 replies; 13+ messages in thread
From: Arnd Bergmann @ 2018-03-15 15:46 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: lkml, Ingo Molnar, John Stultz, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, Deepa Dinamani

On Thu, Mar 15, 2018 at 9:44 AM, Thomas Gleixner <tglx@linutronix.de> wrote:
> On Wed, 14 Mar 2018, Arnd Bergmann wrote:
>>
>>  /*
>> + * legacy timeval structure, only embedded in structures that
>> + * traditionally used 'timeval' to pass time intervals (not absolute
>> + * times). Do not add new users. If user space fails to compile
>> + * here, this is probably because it is not y2038 safe and needs to
>> + * be changed to use another interface.
>> + */
>> +struct __kernel_old_timeval {
>> +     __kernel_long_t tv_sec;                 /* seconds */
>> +     __kernel_long_t tv_usec;                /* microseconds */
>
> Please don't use these horrible tail comments. If you want to document the
> obvious, then please use proper kernel doc.

I just removed them now, the only reason they were there is to keep
the style in sync with the rest of the file, but it's also just a lot of
duplication.

      Arnd

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-03-15 15:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-09 18:42 [GIT PULL][PATCH 0/4] Timekeeping queue for 4.17 John Stultz
2018-03-09 18:42 ` [PATCH 1/4] timekeeping: Don't align frequency adjustments to ticks John Stultz
2018-03-10  9:12   ` [tip:timers/core] timekeeping/ntp: Don't align NTP " tip-bot for Miroslav Lichvar
2018-03-09 18:42 ` [PATCH 2/4] timekeeping: Determine multiplier directly from NTP tick length John Stultz
2018-03-10  9:13   ` [tip:timers/core] timekeeping/ntp: Determine the " tip-bot for Miroslav Lichvar
2018-03-09 18:42 ` [PATCH 3/4] y2038: time: Introduce struct __kernel_old_timeval John Stultz
2018-03-10  8:11   ` Ingo Molnar
2018-03-14 22:02     ` Arnd Bergmann
2018-03-14 22:04       ` [PATCH] [v2] y2038: introduce " Arnd Bergmann
2018-03-15  8:44         ` Thomas Gleixner
2018-03-15 15:46           ` Arnd Bergmann
2018-03-09 18:42 ` [PATCH 4/4] x86: rtc: Stop using rtc deprecated functions John Stultz
2018-03-15  8:52   ` [tip:x86/cleanups] x86/rtc: Stop using " tip-bot for Benjamin Gaignard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).