linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core
@ 2015-04-02  3:34 John Stultz
  2015-04-02  3:34 ` [PATCH 01/21] time: Add y2038 safe read_boot_clock64() John Stultz
                   ` (20 more replies)
  0 siblings, 21 replies; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Peter Zijlstra, Thomas Gleixner, Ingo Molnar,
	Arnd Bergmann, Xunlei Pang

Hey Ingo, Thomas, Peter,

I wanted to send along my remaining 4.1 queue, which contains:

* y2038 fixes for the timekeeping persistent- and boot-clock interfaces.
  (Xunlei)
* y2038 fixes for RTC drivers (Xunlei)
* Small suspend/resume timing fixes (Xunlei)
* Minor cleanups requested by Ingo (Me)

Let me know if you have any objections.

thanks
-john

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Xunlei Pang <pang.xunlei@linaro.org>


John Stultz (3):
  clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50%
    safety margin
  timekeeping: Change timekeeping_check_update() to take a tk_read_base
  time: Rework debugging variables so they aren't global

Xunlei Pang (18):
  time: Add y2038 safe read_boot_clock64()
  time: Add y2038 safe read_persistent_clock64()
  time: Add y2038 safe update_persistent_clock64()
  ARM: OMAP: 32k counter: Provide y2038-safe
    omap_read_persistent_clock() replacement
  ARM: tegra: clock: Provide y2038-safe tegra_read_persistent_clock()
    replacement
  ARM: time: Provide read_boot_clock64() and read_persistent_clock64()
  rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement
  rtc/test: Update driver to address y2038/y2106 issues
  rtc/ab3100: Update driver to address y2038/y2106 issues
  rtc/mc13xxx: Update driver to address y2038/y2106 issues
  rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time
  rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use
    time64_t
  rtc/mxc: Update driver to address y2038/y2106 issues
  alpha: rtc: Change to use rtc_class_ops's set_mmss64()
  time: Don't build timekeeping_inject_sleeptime64() if no one uses it
  rtc: Remove redundant rtc_valid_tm() from rtc_resume()
  time: Fix a bug in timekeeping_suspend() with no persistent clock
  time: rtc: Don't bother into rtc_resume() for the nonstop clocksource

 arch/alpha/kernel/rtc.c             |   8 +-
 arch/arm/include/asm/mach/time.h    |   3 +-
 arch/arm/kernel/time.c              |   6 +-
 arch/arm/plat-omap/counter_32k.c    |  18 ++--
 arch/mips/lasat/sysctl.c            |   4 +-
 drivers/clocksource/tegra20_timer.c |  15 ++-
 drivers/rtc/class.c                 |   8 +-
 drivers/rtc/interface.c             |   8 +-
 drivers/rtc/rtc-ab3100.c            |  55 ++++++-----
 drivers/rtc/rtc-mc13xxx.c           |  32 +++----
 drivers/rtc/rtc-mxc.c               |  55 ++++-------
 drivers/rtc/rtc-test.c              |  19 +++-
 drivers/rtc/systohc.c               |   7 +-
 include/linux/rtc.h                 |   1 +
 include/linux/timekeeper_internal.h |  18 +++-
 include/linux/timekeeping.h         |  12 +--
 kernel/time/clocksource.c           |   7 +-
 kernel/time/ntp.c                   |  13 ++-
 kernel/time/timekeeping.c           | 178 +++++++++++++++++++++---------------
 19 files changed, 261 insertions(+), 206 deletions(-)

-- 
1.9.1


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

* [PATCH 01/21] time: Add y2038 safe read_boot_clock64()
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:15   ` [tip:timers/core] " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 02/21] time: Add y2038 safe read_persistent_clock64() John Stultz
                   ` (19 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

As part of addressing in-kernel y2038 issues, this patch adds
read_boot_clock64() and replaces all the call sites of read_boot_clock()
with this function. This is a __weak implementation, which simply
calls the existing y2038 unsafe read_boot_clock().

This allows architecture specific implementations to be converted
independently, and eventually the y2038 unsafe read_boot_clock()
can be removed after all its architecture specific implementations
have been converted to read_boot_clock64().

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 include/linux/timekeeping.h |  1 +
 kernel/time/timekeeping.c   | 11 +++++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 5047b83..18d27a3 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -269,6 +269,7 @@ static inline bool has_persistent_clock(void)
 
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);
+extern void read_boot_clock64(struct timespec64 *ts);
 extern int update_persistent_clock(struct timespec now);
 
 
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c3fcff0..50c4bec 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1188,6 +1188,14 @@ void __weak read_boot_clock(struct timespec *ts)
 	ts->tv_nsec = 0;
 }
 
+void __weak read_boot_clock64(struct timespec64 *ts64)
+{
+	struct timespec ts;
+
+	read_boot_clock(&ts);
+	*ts64 = timespec_to_timespec64(ts);
+}
+
 /*
  * timekeeping_init - Initializes the clocksource and common timekeeping values
  */
@@ -1209,8 +1217,7 @@ void __init timekeeping_init(void)
 	} else if (now.tv_sec || now.tv_nsec)
 		persistent_clock_exist = true;
 
-	read_boot_clock(&ts);
-	boot = timespec_to_timespec64(ts);
+	read_boot_clock64(&boot);
 	if (!timespec64_valid_strict(&boot)) {
 		pr_warn("WARNING: Boot clock returned invalid value!\n"
 			"         Check your CMOS/BIOS settings.\n");
-- 
1.9.1


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

* [PATCH 02/21] time: Add y2038 safe read_persistent_clock64()
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
  2015-04-02  3:34 ` [PATCH 01/21] time: Add y2038 safe read_boot_clock64() John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:15   ` [tip:timers/core] " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 03/21] time: Add y2038 safe update_persistent_clock64() John Stultz
                   ` (18 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

As part of addressing in-kernel y2038 issues, this patch adds
read_persistent_clock64() and replaces all the call sites of
read_persistent_clock() with this function. This is a __weak
implementation, which simply calls the existing y2038 unsafe
read_persistent_clock().

This allows architecture specific implementations to be converted
independently, and eventually the y2038 unsafe read_persistent_clock()
can be removed after all its architecture specific implementations
have been converted to read_persistent_clock64().

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/mips/lasat/sysctl.c    |  4 ++--
 include/linux/timekeeping.h |  1 +
 kernel/time/timekeeping.c   | 22 ++++++++++++----------
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
index 3b7f65c..cf9b4633 100644
--- a/arch/mips/lasat/sysctl.c
+++ b/arch/mips/lasat/sysctl.c
@@ -75,11 +75,11 @@ static int rtctmp;
 int proc_dolasatrtc(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	int r;
 
 	if (!write) {
-		read_persistent_clock(&ts);
+		read_persistent_clock64(&ts);
 		rtctmp = ts.tv_sec;
 		/* check for time < 0 and set to 0 */
 		if (rtctmp < 0)
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 18d27a3..4c0f76f 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -268,6 +268,7 @@ static inline bool has_persistent_clock(void)
 }
 
 extern void read_persistent_clock(struct timespec *ts);
+extern void read_persistent_clock64(struct timespec64 *ts);
 extern void read_boot_clock(struct timespec *ts);
 extern void read_boot_clock64(struct timespec64 *ts);
 extern int update_persistent_clock(struct timespec now);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 50c4bec..39df498 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1173,6 +1173,14 @@ void __weak read_persistent_clock(struct timespec *ts)
 	ts->tv_nsec = 0;
 }
 
+void __weak read_persistent_clock64(struct timespec64 *ts64)
+{
+	struct timespec ts;
+
+	read_persistent_clock(&ts);
+	*ts64 = timespec_to_timespec64(ts);
+}
+
 /**
  * read_boot_clock -  Return time of the system start.
  *
@@ -1205,10 +1213,8 @@ void __init timekeeping_init(void)
 	struct clocksource *clock;
 	unsigned long flags;
 	struct timespec64 now, boot, tmp;
-	struct timespec ts;
 
-	read_persistent_clock(&ts);
-	now = timespec_to_timespec64(ts);
+	read_persistent_clock64(&now);
 	if (!timespec64_valid_strict(&now)) {
 		pr_warn("WARNING: Persistent clock returned invalid value!\n"
 			"         Check your CMOS/BIOS settings.\n");
@@ -1278,7 +1284,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
  * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
  * @delta: pointer to a timespec64 delta value
  *
- * This hook is for architectures that cannot support read_persistent_clock
+ * This hook is for architectures that cannot support read_persistent_clock64
  * because their RTC/persistent clock is only accessible when irqs are enabled.
  *
  * This function should only be called by rtc_resume(), and allows
@@ -1325,12 +1331,10 @@ void timekeeping_resume(void)
 	struct clocksource *clock = tk->tkr_mono.clock;
 	unsigned long flags;
 	struct timespec64 ts_new, ts_delta;
-	struct timespec tmp;
 	cycle_t cycle_now, cycle_delta;
 	bool suspendtime_found = false;
 
-	read_persistent_clock(&tmp);
-	ts_new = timespec_to_timespec64(tmp);
+	read_persistent_clock64(&ts_new);
 
 	clockevents_resume();
 	clocksource_resume();
@@ -1408,10 +1412,8 @@ int timekeeping_suspend(void)
 	unsigned long flags;
 	struct timespec64		delta, delta_delta;
 	static struct timespec64	old_delta;
-	struct timespec tmp;
 
-	read_persistent_clock(&tmp);
-	timekeeping_suspend_time = timespec_to_timespec64(tmp);
+	read_persistent_clock64(&timekeeping_suspend_time);
 
 	/*
 	 * On some systems the persistent_clock can not be detected at
-- 
1.9.1


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

* [PATCH 03/21] time: Add y2038 safe update_persistent_clock64()
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
  2015-04-02  3:34 ` [PATCH 01/21] time: Add y2038 safe read_boot_clock64() John Stultz
  2015-04-02  3:34 ` [PATCH 02/21] time: Add y2038 safe read_persistent_clock64() John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:16   ` [tip:timers/core] time: Add y2038 safe update_persistent_clock64( ) tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 04/21] ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement John Stultz
                   ` (17 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

As part of addressing in-kernel y2038 issues, this patch adds
update_persistent_clock64() and replaces all the call sites of
update_persistent_clock() with this function. This is a __weak
implementation, which simply calls the existing y2038 unsafe
update_persistent_clock().

This allows architecture specific implementations to be converted
independently, and eventually y2038-unsafe update_persistent_clock()
can be removed after all its architecture specific implementations
have been converted to update_persistent_clock64().

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/systohc.c       |  2 +-
 include/linux/timekeeping.h |  1 +
 kernel/time/ntp.c           | 13 ++++++++++++-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
index eb71872..ef3c07a 100644
--- a/drivers/rtc/systohc.c
+++ b/drivers/rtc/systohc.c
@@ -11,7 +11,7 @@
  * rtc_set_ntp_time - Save NTP synchronized time to the RTC
  * @now: Current time of day
  *
- * Replacement for the NTP platform function update_persistent_clock
+ * Replacement for the NTP platform function update_persistent_clock64
  * that stores time for later retrieval by rtc_hctosys.
  *
  * Returns 0 on successful RTC update, -ENODEV if a RTC update is not
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 4c0f76f..7a2369d 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -272,6 +272,7 @@ extern void read_persistent_clock64(struct timespec64 *ts);
 extern void read_boot_clock(struct timespec *ts);
 extern void read_boot_clock64(struct timespec64 *ts);
 extern int update_persistent_clock(struct timespec now);
+extern int update_persistent_clock64(struct timespec64 now);
 
 
 #endif
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 0f60b08..42d1bc7 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -459,6 +459,16 @@ out:
 	return leap;
 }
 
+#ifdef CONFIG_GENERIC_CMOS_UPDATE
+int __weak update_persistent_clock64(struct timespec64 now64)
+{
+	struct timespec now;
+
+	now = timespec64_to_timespec(now64);
+	return update_persistent_clock(now);
+}
+#endif
+
 #if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC)
 static void sync_cmos_clock(struct work_struct *work);
 
@@ -494,8 +504,9 @@ static void sync_cmos_clock(struct work_struct *work)
 		if (persistent_clock_is_local)
 			adjust.tv_sec -= (sys_tz.tz_minuteswest * 60);
 #ifdef CONFIG_GENERIC_CMOS_UPDATE
-		fail = update_persistent_clock(timespec64_to_timespec(adjust));
+		fail = update_persistent_clock64(adjust);
 #endif
+
 #ifdef CONFIG_RTC_SYSTOHC
 		if (fail == -ENODEV)
 			fail = rtc_set_ntp_time(adjust);
-- 
1.9.1


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

* [PATCH 04/21] ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (2 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 03/21] time: Add y2038 safe update_persistent_clock64() John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:16   ` [tip:timers/core] " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 05/21] ARM: tegra: clock: Provide y2038-safe tegra_read_persistent_clock() replacement John Stultz
                   ` (16 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

As part of addressing "y2038 problem" for in-kernel uses, this
patch adds the y2038-safe omap_read_persistent_clock64() using
timespec64.

Because we rely on some subsequent changes to convert arm multiarch
support, omap_read_persistent_clock() will be removed then.

Also remove the needless spinlock, because read_persistent_clock()
doesn't run simultaneously.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/plat-omap/counter_32k.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 43cf745..b7b7b07 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -44,24 +44,20 @@ static u64 notrace omap_32k_read_sched_clock(void)
 }
 
 /**
- * omap_read_persistent_clock -  Return time from a persistent clock.
+ * omap_read_persistent_clock64 -  Return time from a persistent clock.
  *
  * Reads the time from a source which isn't disabled during PM, the
  * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec.
+ * nsecs and adds to a monotonically increasing timespec64.
  */
-static struct timespec persistent_ts;
+static struct timespec64 persistent_ts;
 static cycles_t cycles;
 static unsigned int persistent_mult, persistent_shift;
-static DEFINE_SPINLOCK(read_persistent_clock_lock);
 
-static void omap_read_persistent_clock(struct timespec *ts)
+static void omap_read_persistent_clock64(struct timespec64 *ts)
 {
 	unsigned long long nsecs;
 	cycles_t last_cycles;
-	unsigned long flags;
-
-	spin_lock_irqsave(&read_persistent_clock_lock, flags);
 
 	last_cycles = cycles;
 	cycles = sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0;
@@ -69,11 +65,17 @@ static void omap_read_persistent_clock(struct timespec *ts)
 	nsecs = clocksource_cyc2ns(cycles - last_cycles,
 					persistent_mult, persistent_shift);
 
-	timespec_add_ns(&persistent_ts, nsecs);
+	timespec64_add_ns(&persistent_ts, nsecs);
 
 	*ts = persistent_ts;
+}
+
+static void omap_read_persistent_clock(struct timespec *ts)
+{
+	struct timespec64 ts64;
 
-	spin_unlock_irqrestore(&read_persistent_clock_lock, flags);
+	omap_read_persistent_clock64(&ts64);
+	*ts = timespec64_to_timespec(ts64);
 }
 
 /**
-- 
1.9.1


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

* [PATCH 05/21] ARM: tegra: clock: Provide y2038-safe tegra_read_persistent_clock() replacement
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (3 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 04/21] ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:16   ` [tip:timers/core] clocksource/drivers/tegra: " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 06/21] ARM: time: Provide read_boot_clock64() and read_persistent_clock64() John Stultz
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

As part of addressing "y2038 problem" for in-kernel uses, this
patch adds the y2038-safe tegra_read_persistent_clock64() using
timespec64.

Because we rely on some subsequent changes to convert arm multiarch
support, tegra_read_persistent_clock() will be removed then.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/clocksource/tegra20_timer.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c
index d8a3a4e..4a0a603 100644
--- a/drivers/clocksource/tegra20_timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -51,7 +51,7 @@
 static void __iomem *timer_reg_base;
 static void __iomem *rtc_base;
 
-static struct timespec persistent_ts;
+static struct timespec64 persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
 
 static struct delay_timer tegra_delay_timer;
@@ -120,26 +120,33 @@ static u64 tegra_rtc_read_ms(void)
 }
 
 /*
- * tegra_read_persistent_clock -  Return time from a persistent clock.
+ * tegra_read_persistent_clock64 -  Return time from a persistent clock.
  *
  * Reads the time from a source which isn't disabled during PM, the
  * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec.
+ * nsecs and adds to a monotonically increasing timespec64.
  * Care must be taken that this funciton is not called while the
  * tegra_rtc driver could be executing to avoid race conditions
  * on the RTC shadow register
  */
-static void tegra_read_persistent_clock(struct timespec *ts)
+static void tegra_read_persistent_clock64(struct timespec64 *ts)
 {
 	u64 delta;
-	struct timespec *tsp = &persistent_ts;
 
 	last_persistent_ms = persistent_ms;
 	persistent_ms = tegra_rtc_read_ms();
 	delta = persistent_ms - last_persistent_ms;
 
-	timespec_add_ns(tsp, delta * NSEC_PER_MSEC);
-	*ts = *tsp;
+	timespec64_add_ns(&persistent_ts, delta * NSEC_PER_MSEC);
+	*ts = persistent_ts;
+}
+
+static void tegra_read_persistent_clock(struct timespec *ts)
+{
+	struct timespec ts64;
+
+	tegra_read_persistent_clock64(&ts64);
+	*ts = timespec64_to_timespec(ts64);
 }
 
 static unsigned long tegra_delay_timer_read_counter_long(void)
-- 
1.9.1


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

* [PATCH 06/21] ARM: time: Provide read_boot_clock64() and read_persistent_clock64()
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (4 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 05/21] ARM: tegra: clock: Provide y2038-safe tegra_read_persistent_clock() replacement John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:17   ` [tip:timers/core] ARM, clocksource/drivers: Provide read_boot_clock64() and read_persistent_clock64() and use them tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 07/21] rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement John Stultz
                   ` (14 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

As part of addressing "y2038 problem" for in-kernel uses, this
patch converts read_boot_clock() to read_boot_clock64() and
read_persistent_clock() to read_persistent_clock64() using
timespec64 by converting clock_access_fn to use timespec64.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Thierry Reding <treding@nvidia.com> (for tegra part)
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/include/asm/mach/time.h    |  3 +--
 arch/arm/kernel/time.c              |  6 +++---
 arch/arm/plat-omap/counter_32k.c    | 10 +---------
 drivers/clocksource/tegra20_timer.c | 10 +---------
 4 files changed, 6 insertions(+), 23 deletions(-)

diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index 90c12e1..0f79e4d 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -12,8 +12,7 @@
 
 extern void timer_tick(void);
 
-struct timespec;
-typedef void (*clock_access_fn)(struct timespec *);
+typedef void (*clock_access_fn)(struct timespec64 *);
 extern int register_persistent_clock(clock_access_fn read_boot,
 				     clock_access_fn read_persistent);
 
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 0cc7e58..a66e37e 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -76,7 +76,7 @@ void timer_tick(void)
 }
 #endif
 
-static void dummy_clock_access(struct timespec *ts)
+static void dummy_clock_access(struct timespec64 *ts)
 {
 	ts->tv_sec = 0;
 	ts->tv_nsec = 0;
@@ -85,12 +85,12 @@ static void dummy_clock_access(struct timespec *ts)
 static clock_access_fn __read_persistent_clock = dummy_clock_access;
 static clock_access_fn __read_boot_clock = dummy_clock_access;;
 
-void read_persistent_clock(struct timespec *ts)
+void read_persistent_clock64(struct timespec64 *ts)
 {
 	__read_persistent_clock(ts);
 }
 
-void read_boot_clock(struct timespec *ts)
+void read_boot_clock64(struct timespec64 *ts)
 {
 	__read_boot_clock(ts);
 }
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index b7b7b07..2438b96 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -70,14 +70,6 @@ static void omap_read_persistent_clock64(struct timespec64 *ts)
 	*ts = persistent_ts;
 }
 
-static void omap_read_persistent_clock(struct timespec *ts)
-{
-	struct timespec64 ts64;
-
-	omap_read_persistent_clock64(&ts64);
-	*ts = timespec64_to_timespec(ts64);
-}
-
 /**
  * omap_init_clocksource_32k - setup and register counter 32k as a
  * kernel clocksource
@@ -118,7 +110,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase)
 	}
 
 	sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
-	register_persistent_clock(NULL, omap_read_persistent_clock);
+	register_persistent_clock(NULL, omap_read_persistent_clock64);
 	pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
 
 	return 0;
diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c
index 4a0a603..5a112d7 100644
--- a/drivers/clocksource/tegra20_timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -141,14 +141,6 @@ static void tegra_read_persistent_clock64(struct timespec64 *ts)
 	*ts = persistent_ts;
 }
 
-static void tegra_read_persistent_clock(struct timespec *ts)
-{
-	struct timespec ts64;
-
-	tegra_read_persistent_clock64(&ts64);
-	*ts = timespec64_to_timespec(ts64);
-}
-
 static unsigned long tegra_delay_timer_read_counter_long(void)
 {
 	return readl(timer_reg_base + TIMERUS_CNTR_1US);
@@ -259,7 +251,7 @@ static void __init tegra20_init_rtc(struct device_node *np)
 	else
 		clk_prepare_enable(clk);
 
-	register_persistent_clock(NULL, tegra_read_persistent_clock);
+	register_persistent_clock(NULL, tegra_read_persistent_clock64);
 }
 CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
 
-- 
1.9.1


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

* [PATCH 07/21] rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (5 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 06/21] ARM: time: Provide read_boot_clock64() and read_persistent_clock64() John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:17   ` [tip:timers/core] drivers/rtc: " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 08/21] rtc/test: Update driver to address y2038/y2106 issues John Stultz
                   ` (13 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

Currently the rtc_class_op's set_mmss() function takes a 32bit second
value (on 32bit systems), which is problematic for dates past y2038.

This patch provides a safe version named set_mmss64() using y2038 safe
time64_t.

After this patch, set_mmss() is deprecated and all its users will be
fixed to use set_mmss64(), it can be removed when having no users.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
[jstultz: Add whitespace fix for checkpatch]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/interface.c | 8 +++++++-
 drivers/rtc/systohc.c   | 5 ++++-
 include/linux/rtc.h     | 1 +
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 37215cf..d43ee40 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -72,7 +72,11 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
 		err = -ENODEV;
 	else if (rtc->ops->set_time)
 		err = rtc->ops->set_time(rtc->dev.parent, tm);
-	else if (rtc->ops->set_mmss) {
+	else if (rtc->ops->set_mmss64) {
+		time64_t secs64 = rtc_tm_to_time64(tm);
+
+		err = rtc->ops->set_mmss64(rtc->dev.parent, secs64);
+	} else if (rtc->ops->set_mmss) {
 		time64_t secs64 = rtc_tm_to_time64(tm);
 		err = rtc->ops->set_mmss(rtc->dev.parent, secs64);
 	} else
@@ -96,6 +100,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
 
 	if (!rtc->ops)
 		err = -ENODEV;
+	else if (rtc->ops->set_mmss64)
+		err = rtc->ops->set_mmss64(rtc->dev.parent, secs);
 	else if (rtc->ops->set_mmss)
 		err = rtc->ops->set_mmss(rtc->dev.parent, secs);
 	else if (rtc->ops->read_time && rtc->ops->set_time) {
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
index ef3c07a..7728d5e 100644
--- a/drivers/rtc/systohc.c
+++ b/drivers/rtc/systohc.c
@@ -35,7 +35,10 @@ int rtc_set_ntp_time(struct timespec64 now)
 	if (rtc) {
 		/* rtc_hctosys exclusively uses UTC, so we call set_time here,
 		 * not set_mmss. */
-		if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss))
+		if (rtc->ops &&
+		    (rtc->ops->set_time ||
+		     rtc->ops->set_mmss64 ||
+		     rtc->ops->set_mmss))
 			err = rtc_set_time(rtc, &tm);
 		rtc_class_close(rtc);
 	}
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index dcad7ee..8dcf682 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -77,6 +77,7 @@ struct rtc_class_ops {
 	int (*read_alarm)(struct device *, struct rtc_wkalrm *);
 	int (*set_alarm)(struct device *, struct rtc_wkalrm *);
 	int (*proc)(struct device *, struct seq_file *);
+	int (*set_mmss64)(struct device *, time64_t secs);
 	int (*set_mmss)(struct device *, unsigned long secs);
 	int (*read_callback)(struct device *, int data);
 	int (*alarm_irq_enable)(struct device *, unsigned int enabled);
-- 
1.9.1


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

* [PATCH 08/21] rtc/test: Update driver to address y2038/y2106 issues
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (6 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 07/21] rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:17   ` [tip:timers/core] drivers/rtc/test: " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 09/21] rtc/ab3100: " John Stultz
                   ` (12 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

This driver has a number of y2038/y2106 issues.

This patch resolves them by:
- Repalce get_seconds() with ktime_get_real_seconds()
- Replace rtc_time_to_tm() with rtc_time64_to_tm()

Also add test_rtc_set_mmss64() for testing rtc_class_ops's
set_mmss64(), which can be activated by "test_mmss64" module
parameter.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/rtc-test.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index 8f86fa9..3a2da4c 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -13,6 +13,10 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 
+static int test_mmss64;
+module_param(test_mmss64, int, 0644);
+MODULE_PARM_DESC(test_mmss64, "Test struct rtc_class_ops.set_mmss64().");
+
 static struct platform_device *test0 = NULL, *test1 = NULL;
 
 static int test_rtc_read_alarm(struct device *dev,
@@ -30,7 +34,13 @@ static int test_rtc_set_alarm(struct device *dev,
 static int test_rtc_read_time(struct device *dev,
 	struct rtc_time *tm)
 {
-	rtc_time_to_tm(get_seconds(), tm);
+	rtc_time64_to_tm(ktime_get_real_seconds(), tm);
+	return 0;
+}
+
+static int test_rtc_set_mmss64(struct device *dev, time64_t secs)
+{
+	dev_info(dev, "%s, secs = %lld\n", __func__, (long long)secs);
 	return 0;
 }
 
@@ -55,7 +65,7 @@ static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
 	return 0;
 }
 
-static const struct rtc_class_ops test_rtc_ops = {
+static struct rtc_class_ops test_rtc_ops = {
 	.proc = test_rtc_proc,
 	.read_time = test_rtc_read_time,
 	.read_alarm = test_rtc_read_alarm,
@@ -101,6 +111,11 @@ static int test_probe(struct platform_device *plat_dev)
 	int err;
 	struct rtc_device *rtc;
 
+	if (test_mmss64) {
+		test_rtc_ops.set_mmss64 = test_rtc_set_mmss64;
+		test_rtc_ops.set_mmss = NULL;
+	}
+
 	rtc = devm_rtc_device_register(&plat_dev->dev, "test",
 				&test_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc)) {
-- 
1.9.1


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

* [PATCH 09/21] rtc/ab3100: Update driver to address y2038/y2106 issues
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (7 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 08/21] rtc/test: Update driver to address y2038/y2106 issues John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:17   ` [tip:timers/core] drivers/rtc/ab3100: " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 10/21] rtc/mc13xxx: " John Stultz
                   ` (11 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

This driver has a number of y2038/y2106 issues.

This patch resolves them by:
- Replace rtc_tm_to_time() with rtc_tm_to_time64()
- Replace rtc_time_to_tm() with rtc_time64_to_tm()
- Change ab3100_rtc_set_mmss() to use rtc_class_ops's set_mmss64()

After this patch, the driver should not have any remaining
y2038/y2106 issues.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/rtc-ab3100.c | 55 ++++++++++++++++++++++++------------------------
 1 file changed, 27 insertions(+), 28 deletions(-)

diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c
index 1d0340f..9b725c5 100644
--- a/drivers/rtc/rtc-ab3100.c
+++ b/drivers/rtc/rtc-ab3100.c
@@ -43,21 +43,21 @@
 /*
  * RTC clock functions and device struct declaration
  */
-static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int ab3100_rtc_set_mmss(struct device *dev, time64_t secs)
 {
 	u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2,
 		     AB3100_TI3, AB3100_TI4, AB3100_TI5};
 	unsigned char buf[6];
-	u64 fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2;
+	u64 hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2;
 	int err = 0;
 	int i;
 
-	buf[0] = (fat_time) & 0xFF;
-	buf[1] = (fat_time >> 8) & 0xFF;
-	buf[2] = (fat_time >> 16) & 0xFF;
-	buf[3] = (fat_time >> 24) & 0xFF;
-	buf[4] = (fat_time >> 32) & 0xFF;
-	buf[5] = (fat_time >> 40) & 0xFF;
+	buf[0] = (hw_counter) & 0xFF;
+	buf[1] = (hw_counter >> 8) & 0xFF;
+	buf[2] = (hw_counter >> 16) & 0xFF;
+	buf[3] = (hw_counter >> 24) & 0xFF;
+	buf[4] = (hw_counter >> 32) & 0xFF;
+	buf[5] = (hw_counter >> 40) & 0xFF;
 
 	for (i = 0; i < 6; i++) {
 		err = abx500_set_register_interruptible(dev, 0,
@@ -75,7 +75,7 @@ static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs)
 
 static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	unsigned long time;
+	time64_t time;
 	u8 rtcval;
 	int err;
 
@@ -88,7 +88,7 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 		dev_info(dev, "clock not set (lost power)");
 		return -EINVAL;
 	} else {
-		u64 fat_time;
+		u64 hw_counter;
 		u8 buf[6];
 
 		/* Read out time registers */
@@ -98,22 +98,21 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 		if (err != 0)
 			return err;
 
-		fat_time = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
+		hw_counter = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
 			((u64) buf[3] << 24) | ((u64) buf[2] << 16) |
 			((u64) buf[1] << 8) | (u64) buf[0];
-		time = (unsigned long) (fat_time /
-					(u64) (AB3100_RTC_CLOCK_RATE * 2));
+		time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
 	}
 
-	rtc_time_to_tm(time, tm);
+	rtc_time64_to_tm(time, tm);
 
 	return rtc_valid_tm(tm);
 }
 
 static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	unsigned long time;
-	u64 fat_time;
+	time64_t time;
+	u64 hw_counter;
 	u8 buf[6];
 	u8 rtcval;
 	int err;
@@ -134,11 +133,11 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 						     AB3100_AL0, buf, 4);
 	if (err)
 		return err;
-	fat_time = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
+	hw_counter = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
 		((u64) buf[1] << 24) | ((u64) buf[0] << 16);
-	time = (unsigned long) (fat_time / (u64) (AB3100_RTC_CLOCK_RATE * 2));
+	time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
 
-	rtc_time_to_tm(time, &alarm->time);
+	rtc_time64_to_tm(time, &alarm->time);
 
 	return rtc_valid_tm(&alarm->time);
 }
@@ -147,17 +146,17 @@ static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3};
 	unsigned char buf[4];
-	unsigned long secs;
-	u64 fat_time;
+	time64_t secs;
+	u64 hw_counter;
 	int err;
 	int i;
 
-	rtc_tm_to_time(&alarm->time, &secs);
-	fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2;
-	buf[0] = (fat_time >> 16) & 0xFF;
-	buf[1] = (fat_time >> 24) & 0xFF;
-	buf[2] = (fat_time >> 32) & 0xFF;
-	buf[3] = (fat_time >> 40) & 0xFF;
+	secs = rtc_tm_to_time64(&alarm->time);
+	hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2;
+	buf[0] = (hw_counter >> 16) & 0xFF;
+	buf[1] = (hw_counter >> 24) & 0xFF;
+	buf[2] = (hw_counter >> 32) & 0xFF;
+	buf[3] = (hw_counter >> 40) & 0xFF;
 
 	/* Set the alarm */
 	for (i = 0; i < 4; i++) {
@@ -193,7 +192,7 @@ static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled)
 
 static const struct rtc_class_ops ab3100_rtc_ops = {
 	.read_time	= ab3100_rtc_read_time,
-	.set_mmss	= ab3100_rtc_set_mmss,
+	.set_mmss64	= ab3100_rtc_set_mmss,
 	.read_alarm	= ab3100_rtc_read_alarm,
 	.set_alarm	= ab3100_rtc_set_alarm,
 	.alarm_irq_enable = ab3100_rtc_irq_enable,
-- 
1.9.1


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

* [PATCH 10/21] rtc/mc13xxx: Update driver to address y2038/y2106 issues
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (8 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 09/21] rtc/ab3100: " John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:18   ` [tip:timers/core] drivers/rtc/mc13xxx: " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 11/21] rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time John Stultz
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

This driver has a number of y2038/y2106 issues.

This patch resolves them by:
- Replace rtc_time_to_tm() with rtc_time64_to_tm()
- Change mc13xxx_rtc_set_mmss() to use rtc_class_ops's set_mmss64()

After this patch, the driver should not have any remaining
y2038/y2106 issues.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/rtc-mc13xxx.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index 5bce904b..32df1d8 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -83,20 +83,19 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
 			return ret;
 	} while (days1 != days2);
 
-	rtc_time_to_tm(days1 * SEC_PER_DAY + seconds, tm);
+	rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm);
 
 	return rtc_valid_tm(tm);
 }
 
-static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 	unsigned int seconds, days;
 	unsigned int alarmseconds;
 	int ret;
 
-	seconds = secs % SEC_PER_DAY;
-	days = secs / SEC_PER_DAY;
+	days = div_s64_rem(secs, SEC_PER_DAY, &seconds);
 
 	mc13xxx_lock(priv->mc13xxx);
 
@@ -159,7 +158,7 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 	unsigned seconds, days;
-	unsigned long s1970;
+	time64_t s1970;
 	int enabled, pending;
 	int ret;
 
@@ -189,10 +188,10 @@ out:
 	alarm->enabled = enabled;
 	alarm->pending = pending;
 
-	s1970 = days * SEC_PER_DAY + seconds;
+	s1970 = (time64_t)days * SEC_PER_DAY + seconds;
 
-	rtc_time_to_tm(s1970, &alarm->time);
-	dev_dbg(dev, "%s: %lu\n", __func__, s1970);
+	rtc_time64_to_tm(s1970, &alarm->time);
+	dev_dbg(dev, "%s: %lld\n", __func__, (long long)s1970);
 
 	return 0;
 }
@@ -200,8 +199,8 @@ out:
 static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
-	unsigned long s1970;
-	unsigned seconds, days;
+	time64_t s1970;
+	u32 seconds, days;
 	int ret;
 
 	mc13xxx_lock(priv->mc13xxx);
@@ -215,20 +214,17 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (unlikely(ret))
 		goto out;
 
-	ret = rtc_tm_to_time(&alarm->time, &s1970);
-	if (unlikely(ret))
-		goto out;
+	s1970 = rtc_tm_to_time64(&alarm->time);
 
-	dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
-			s1970);
+	dev_dbg(dev, "%s: o%2.s %lld\n", __func__, alarm->enabled ? "n" : "ff",
+			(long long)s1970);
 
 	ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled,
 			MC13XXX_IRQ_TODA);
 	if (unlikely(ret))
 		goto out;
 
-	seconds = s1970 % SEC_PER_DAY;
-	days = s1970 / SEC_PER_DAY;
+	days = div_s64_rem(s1970, SEC_PER_DAY, &seconds);
 
 	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days);
 	if (unlikely(ret))
@@ -268,7 +264,7 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
 
 static const struct rtc_class_ops mc13xxx_rtc_ops = {
 	.read_time = mc13xxx_rtc_read_time,
-	.set_mmss = mc13xxx_rtc_set_mmss,
+	.set_mmss64 = mc13xxx_rtc_set_mmss,
 	.read_alarm = mc13xxx_rtc_read_alarm,
 	.set_alarm = mc13xxx_rtc_set_alarm,
 	.alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable,
-- 
1.9.1


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

* [PATCH 11/21] rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (9 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 10/21] rtc/mc13xxx: " John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:18   ` [tip:timers/core] drivers/rtc/mxc: " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 12/21] rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use time64_t John Stultz
                   ` (9 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

rtc_class_ops's set_alarm() shouldn't deal with the alarm date,
as this is handled in the rtc core.

See rtc_dev_ioctl()'s RTC_ALM_SET and RTC_WKALM_SET cases.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/rtc-mxc.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 3c3f8d1..a7b218f 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -173,29 +173,18 @@ static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time)
  * This function updates the RTC alarm registers and then clears all the
  * interrupt status bits.
  */
-static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
+static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
 {
-	struct rtc_time alarm_tm, now_tm;
-	unsigned long now, time;
+	unsigned long time;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	now = get_alarm_or_time(dev, MXC_RTC_TIME);
-	rtc_time_to_tm(now, &now_tm);
-	alarm_tm.tm_year = now_tm.tm_year;
-	alarm_tm.tm_mon = now_tm.tm_mon;
-	alarm_tm.tm_mday = now_tm.tm_mday;
-	alarm_tm.tm_hour = alrm->tm_hour;
-	alarm_tm.tm_min = alrm->tm_min;
-	alarm_tm.tm_sec = alrm->tm_sec;
-	rtc_tm_to_time(&alarm_tm, &time);
+	rtc_tm_to_time(alrm, &time);
 
 	/* clear all the interrupt status bits */
 	writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR);
 	set_alarm_or_time(dev, MXC_RTC_ALARM, time);
-
-	return 0;
 }
 
 static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
@@ -346,11 +335,8 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-	int ret;
 
-	ret = rtc_update_alarm(dev, &alrm->time);
-	if (ret)
-		return ret;
+	rtc_update_alarm(dev, &alrm->time);
 
 	memcpy(&pdata->g_rtc_alarm, &alrm->time, sizeof(struct rtc_time));
 	mxc_rtc_irq_enable(dev, RTC_ALM_BIT, alrm->enabled);
-- 
1.9.1


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

* [PATCH 12/21] rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use time64_t
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (10 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 11/21] rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:18   ` [tip:timers/core] drivers/rtc/mxc: Convert get_alarm_or_time()/ set_alarm_or_time() " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 13/21] rtc/mxc: Update driver to address y2038/y2106 issues John Stultz
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

We want to convert mxc_rtc_set_mmss() to use rtc_class_ops's set_mmss64(),
but it uses get_alarm_or_time()/set_alarm_or_time() internal interfaces
which are y2038 unsafe.

So here as a separate patch, it converts these two internal interfaces
of "mxc" to use safe time64_t to make some preparations.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/rtc-mxc.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index a7b218f..83cba23 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -106,7 +106,7 @@ static inline int is_imx1_rtc(struct rtc_plat_data *data)
  * This function is used to obtain the RTC time or the alarm value in
  * second.
  */
-static u32 get_alarm_or_time(struct device *dev, int time_alarm)
+static time64_t get_alarm_or_time(struct device *dev, int time_alarm)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
@@ -129,29 +129,28 @@ static u32 get_alarm_or_time(struct device *dev, int time_alarm)
 	hr = hr_min >> 8;
 	min = hr_min & 0xff;
 
-	return (((day * 24 + hr) * 60) + min) * 60 + sec;
+	return ((((time64_t)day * 24 + hr) * 60) + min) * 60 + sec;
 }
 
 /*
  * This function sets the RTC alarm value or the time value.
  */
-static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time)
+static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time)
 {
-	u32 day, hr, min, sec, temp;
+	u32 tod, day, hr, min, sec, temp;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	day = time / 86400;
-	time -= day * 86400;
+	day = div_s64_rem(time, 86400, &tod);
 
 	/* time is within a day now */
-	hr = time / 3600;
-	time -= hr * 3600;
+	hr = tod / 3600;
+	tod -= hr * 3600;
 
 	/* time is within an hour now */
-	min = time / 60;
-	sec = time - min * 60;
+	min = tod / 60;
+	sec = tod - min * 60;
 
 	temp = (hr << 8) + min;
 
@@ -175,12 +174,12 @@ static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time)
  */
 static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
 {
-	unsigned long time;
+	time64_t time;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	rtc_tm_to_time(alrm, &time);
+	time = rtc_tm_to_time64(alrm);
 
 	/* clear all the interrupt status bits */
 	writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR);
@@ -272,14 +271,14 @@ static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  */
 static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	u32 val;
+	time64_t val;
 
 	/* Avoid roll-over from reading the different registers */
 	do {
 		val = get_alarm_or_time(dev, MXC_RTC_TIME);
 	} while (val != get_alarm_or_time(dev, MXC_RTC_TIME));
 
-	rtc_time_to_tm(val, tm);
+	rtc_time64_to_tm(val, tm);
 
 	return 0;
 }
@@ -322,7 +321,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	rtc_time_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time);
+	rtc_time64_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time);
 	alrm->pending = ((readw(ioaddr + RTC_RTCISR) & RTC_ALM_BIT)) ? 1 : 0;
 
 	return 0;
-- 
1.9.1


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

* [PATCH 13/21] rtc/mxc: Update driver to address y2038/y2106 issues
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (11 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 12/21] rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use time64_t John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:19   ` [tip:timers/core] drivers/rtc/mxc: Update driver to address y2038 /y2106 issues tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 14/21] alpha: rtc: Change to use rtc_class_ops's set_mmss64() John Stultz
                   ` (7 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

This driver has a number of y2038/y2106 issues.

This patch resolves them by:
- Replace rtc_time_to_tm() with rtc_time64_to_tm()
- Replace rtc_tm_to_time() with rtc_tm_to_time64()
- Change mxc_rtc_set_mmss() to use rtc_class_ops's set_mmss64()

After this patch, the driver should not have any remaining
y2038/y2106 issues.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/rtc-mxc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 83cba23..09d422b 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -286,7 +286,7 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
 /*
  * This function sets the internal RTC time based on tm in Gregorian date.
  */
-static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
+static int mxc_rtc_set_mmss(struct device *dev, time64_t time)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
@@ -297,9 +297,9 @@ static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
 	if (is_imx1_rtc(pdata)) {
 		struct rtc_time tm;
 
-		rtc_time_to_tm(time, &tm);
+		rtc_time64_to_tm(time, &tm);
 		tm.tm_year = 70;
-		rtc_tm_to_time(&tm, &time);
+		time = rtc_tm_to_time64(&tm);
 	}
 
 	/* Avoid roll-over from reading the different registers */
@@ -347,7 +347,7 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static struct rtc_class_ops mxc_rtc_ops = {
 	.release		= mxc_rtc_release,
 	.read_time		= mxc_rtc_read_time,
-	.set_mmss		= mxc_rtc_set_mmss,
+	.set_mmss64		= mxc_rtc_set_mmss,
 	.read_alarm		= mxc_rtc_read_alarm,
 	.set_alarm		= mxc_rtc_set_alarm,
 	.alarm_irq_enable	= mxc_rtc_alarm_irq_enable,
-- 
1.9.1


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

* [PATCH 14/21] alpha: rtc: Change to use rtc_class_ops's set_mmss64()
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (12 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 13/21] rtc/mxc: Update driver to address y2038/y2106 issues John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:19   ` [tip:timers/core] alpha, rtc: Change to use rtc_class_ops' s set_mmss64() tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 15/21] time: Don't build timekeeping_inject_sleeptime64() if no one uses it John Stultz
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

Change alpha_rtc_set_mmss() and remote_set_mmss() to use
rtc_class_ops's set_mmss64().

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/alpha/kernel/rtc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c
index c8d284d..f535a3f 100644
--- a/arch/alpha/kernel/rtc.c
+++ b/arch/alpha/kernel/rtc.c
@@ -116,7 +116,7 @@ alpha_rtc_set_time(struct device *dev, struct rtc_time *tm)
 }
 
 static int
-alpha_rtc_set_mmss(struct device *dev, unsigned long nowtime)
+alpha_rtc_set_mmss(struct device *dev, time64_t nowtime)
 {
 	int retval = 0;
 	int real_seconds, real_minutes, cmos_minutes;
@@ -211,7 +211,7 @@ alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 static const struct rtc_class_ops alpha_rtc_ops = {
 	.read_time = alpha_rtc_read_time,
 	.set_time = alpha_rtc_set_time,
-	.set_mmss = alpha_rtc_set_mmss,
+	.set_mmss64 = alpha_rtc_set_mmss,
 	.ioctl = alpha_rtc_ioctl,
 };
 
@@ -276,7 +276,7 @@ do_remote_mmss(void *data)
 }
 
 static int
-remote_set_mmss(struct device *dev, unsigned long now)
+remote_set_mmss(struct device *dev, time64_t now)
 {
 	union remote_data x;
 	if (smp_processor_id() != boot_cpuid) {
@@ -290,7 +290,7 @@ remote_set_mmss(struct device *dev, unsigned long now)
 static const struct rtc_class_ops remote_rtc_ops = {
 	.read_time = remote_read_time,
 	.set_time = remote_set_time,
-	.set_mmss = remote_set_mmss,
+	.set_mmss64 = remote_set_mmss,
 	.ioctl = alpha_rtc_ioctl,
 };
 #endif
-- 
1.9.1


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

* [PATCH 15/21] time: Don't build timekeeping_inject_sleeptime64() if no one uses it
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (13 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 14/21] alpha: rtc: Change to use rtc_class_ops's set_mmss64() John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:19   ` [tip:timers/core] time: Don' t " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 16/21] rtc: Remove redundant rtc_valid_tm() from rtc_resume() John Stultz
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

timekeeping_inject_sleeptime64() is only used by RTC suspend/resume,
so add build dependencies on the necessary RTC related macros.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
[jstultz: Improve commit message clarity]
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/timekeeping.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 39df498..7d799d3 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1280,6 +1280,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
 	tk_debug_account_sleep_time(delta);
 }
 
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
 /**
  * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
  * @delta: pointer to a timespec64 delta value
@@ -1317,6 +1318,7 @@ void timekeeping_inject_sleeptime64(struct timespec64 *delta)
 	/* signal hrtimers about time change */
 	clock_was_set();
 }
+#endif
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
-- 
1.9.1


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

* [PATCH 16/21] rtc: Remove redundant rtc_valid_tm() from rtc_resume()
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (14 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 15/21] time: Don't build timekeeping_inject_sleeptime64() if no one uses it John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:19   ` [tip:timers/core] drivers/rtc: " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 17/21] time: Fix a bug in timekeeping_suspend() with no persistent clock John Stultz
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

rtc_read_time() has already judged valid tm by rtc_valid_tm(),
so just remove it.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/class.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 472a5ad..d40760a 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -117,10 +117,6 @@ static int rtc_resume(struct device *dev)
 		return 0;
 	}
 
-	if (rtc_valid_tm(&tm) != 0) {
-		pr_debug("%s:  bogus resume time\n", dev_name(&rtc->dev));
-		return 0;
-	}
 	new_rtc.tv_sec = rtc_tm_to_time64(&tm);
 	new_rtc.tv_nsec = 0;
 
-- 
1.9.1


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

* [PATCH 17/21] time: Fix a bug in timekeeping_suspend() with no persistent clock
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (15 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 16/21] rtc: Remove redundant rtc_valid_tm() from rtc_resume() John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  6:16   ` Ingo Molnar
  2015-04-03  8:20   ` [tip:timers/core] " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 18/21] time: rtc: Don't bother into rtc_resume() for the nonstop clocksource John Stultz
                   ` (3 subsequent siblings)
  20 siblings, 2 replies; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

When there's no persistent clock, normally timekeeping_suspend_time
should always be zero, but this can break in timekeeping_suspend().

At T1, there was a system suspend, so old_delta was assigned T1.
After some time, one time adjustment happened, and xtime got the
value of T1-dt(0s<dt<2s). Then, there comes another system suspend
soon after this adjustment, obviously we will get a small negative
delta_delta, resulting in a negative timekeeping_suspend_time.

This is problematic, when doing timekeeping_resume() if there is
no nonstop clocksource for example, it will hit the else leg and
inject the improper sleeptime which is the wrong logic.

So, we can solve this problem by only doing delta related code when
the persistent clock is existent. Actually the code only makes sense
for persistent clock cases.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/timekeeping.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 7d799d3..6dafcea 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1255,7 +1255,7 @@ void __init timekeeping_init(void)
 	raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
 }
 
-/* time in seconds when suspend began */
+/* time in seconds when suspend began for persistent clock */
 static struct timespec64 timekeeping_suspend_time;
 
 /**
@@ -1430,24 +1430,26 @@ int timekeeping_suspend(void)
 	timekeeping_forward_now(tk);
 	timekeeping_suspended = 1;
 
-	/*
-	 * To avoid drift caused by repeated suspend/resumes,
-	 * which each can add ~1 second drift error,
-	 * try to compensate so the difference in system time
-	 * and persistent_clock time stays close to constant.
-	 */
-	delta = timespec64_sub(tk_xtime(tk), timekeeping_suspend_time);
-	delta_delta = timespec64_sub(delta, old_delta);
-	if (abs(delta_delta.tv_sec)  >= 2) {
+	if (has_persistent_clock()) {
 		/*
-		 * if delta_delta is too large, assume time correction
-		 * has occured and set old_delta to the current delta.
+		 * To avoid drift caused by repeated suspend/resumes,
+		 * which each can add ~1 second drift error,
+		 * try to compensate so the difference in system time
+		 * and persistent_clock time stays close to constant.
 		 */
-		old_delta = delta;
-	} else {
-		/* Otherwise try to adjust old_system to compensate */
-		timekeeping_suspend_time =
-			timespec64_add(timekeeping_suspend_time, delta_delta);
+		delta = timespec64_sub(tk_xtime(tk), timekeeping_suspend_time);
+		delta_delta = timespec64_sub(delta, old_delta);
+		if (abs(delta_delta.tv_sec) >= 2) {
+			/*
+			 * if delta_delta is too large, assume time correction
+			 * has occurred and set old_delta to the current delta.
+			 */
+			old_delta = delta;
+		} else {
+			/* Otherwise try to adjust old_system to compensate */
+			timekeeping_suspend_time =
+				timespec64_add(timekeeping_suspend_time, delta_delta);
+		}
 	}
 
 	timekeeping_update(tk, TK_MIRROR);
-- 
1.9.1


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

* [PATCH 18/21] time: rtc: Don't bother into rtc_resume() for the nonstop clocksource
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (16 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 17/21] time: Fix a bug in timekeeping_suspend() with no persistent clock John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-03  8:20   ` [tip:timers/core] time, drivers/rtc: Don't bother with rtc_resume () " tip-bot for Xunlei Pang
  2015-04-02  3:34 ` [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin John Stultz
                   ` (2 subsequent siblings)
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: Xunlei Pang, Peter Zijlstra, Thomas Gleixner, Ingo Molnar, John Stultz

From: Xunlei Pang <pang.xunlei@linaro.org>

If a system does not provide a persistent_clock(), the time
will be updated on resume by rtc_resume(). With the addition
of the non-stop clocksources for suspend timing, those systems
set the time on resume in timekeeping_resume(), but may not
provide a valid persistent_clock().

This results in the rtc_resume() logic thinking no one has set
the time and it then will over-write the suspend time again,
which is not necessary and only increases clock error.

So, fix this for rtc_resume().

This patch also improves the name of persistent_clock_exist to
make it more grammatical.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 drivers/rtc/class.c         |  4 +--
 include/linux/timekeeping.h |  9 +++----
 kernel/time/timekeeping.c   | 66 +++++++++++++++++++++++++++++++++------------
 3 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index d40760a..c29ba7e 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -55,7 +55,7 @@ static int rtc_suspend(struct device *dev)
 	struct timespec64	delta, delta_delta;
 	int err;
 
-	if (has_persistent_clock())
+	if (timekeeping_rtc_skipsuspend())
 		return 0;
 
 	if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
@@ -102,7 +102,7 @@ static int rtc_resume(struct device *dev)
 	struct timespec64	sleep_time;
 	int err;
 
-	if (has_persistent_clock())
+	if (timekeeping_rtc_skipresume())
 		return 0;
 
 	rtc_hctosys_ret = -ENODEV;
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 7a2369d..99176af 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -248,6 +248,9 @@ static inline void timekeeping_clocktai(struct timespec *ts)
 /*
  * RTC specific
  */
+extern bool timekeeping_rtc_skipsuspend(void);
+extern bool timekeeping_rtc_skipresume(void);
+
 extern void timekeeping_inject_sleeptime64(struct timespec64 *delta);
 
 /*
@@ -259,14 +262,8 @@ extern void getnstime_raw_and_real(struct timespec *ts_raw,
 /*
  * Persistent clock related interfaces
  */
-extern bool persistent_clock_exist;
 extern int persistent_clock_is_local;
 
-static inline bool has_persistent_clock(void)
-{
-	return persistent_clock_exist;
-}
-
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_persistent_clock64(struct timespec64 *ts);
 extern void read_boot_clock(struct timespec *ts);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 6dafcea..fe91e8e 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -64,9 +64,6 @@ static struct tk_fast tk_fast_raw  ____cacheline_aligned;
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
 
-/* Flag for if there is a persistent clock on this platform */
-bool __read_mostly persistent_clock_exist = false;
-
 static inline void tk_normalize_xtime(struct timekeeper *tk)
 {
 	while (tk->tkr_mono.xtime_nsec >= ((u64)NSEC_PER_SEC << tk->tkr_mono.shift)) {
@@ -1204,6 +1201,12 @@ void __weak read_boot_clock64(struct timespec64 *ts64)
 	*ts64 = timespec_to_timespec64(ts);
 }
 
+/* Flag for if timekeeping_resume() has injected sleeptime */
+static bool sleeptime_injected;
+
+/* Flag for if there is a persistent clock on this platform */
+static bool persistent_clock_exists;
+
 /*
  * timekeeping_init - Initializes the clocksource and common timekeeping values
  */
@@ -1221,7 +1224,7 @@ void __init timekeeping_init(void)
 		now.tv_sec = 0;
 		now.tv_nsec = 0;
 	} else if (now.tv_sec || now.tv_nsec)
-		persistent_clock_exist = true;
+		persistent_clock_exists = true;
 
 	read_boot_clock64(&boot);
 	if (!timespec64_valid_strict(&boot)) {
@@ -1282,11 +1285,47 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
 
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
 /**
+ * We have three kinds of time sources to use for sleep time
+ * injection, the preference order is:
+ * 1) non-stop clocksource
+ * 2) persistent clock (ie: RTC accessible when irqs are off)
+ * 3) RTC
+ *
+ * 1) and 2) are used by timekeeping, 3) by RTC subsystem.
+ * If system has neither 1) nor 2), 3) will be used finally.
+ *
+ *
+ * If timekeeping has injected sleeptime via either 1) or 2),
+ * 3) becomes needless, so in this case we don't need to call
+ * rtc_resume(), and this is what timekeeping_rtc_skipresume()
+ * means.
+ */
+bool timekeeping_rtc_skipresume(void)
+{
+	return sleeptime_injected;
+}
+
+/**
+ * 1) can be determined whether to use or not only when doing
+ * timekeeping_resume() which is invoked after rtc_suspend(),
+ * so we can't skip rtc_suspend() surely if system has 1).
+ *
+ * But if system has 2), 2) will definitely be used, so in this
+ * case we don't need to call rtc_suspend(), and this is what
+ * timekeeping_rtc_skipsuspend() means.
+ */
+bool timekeeping_rtc_skipsuspend(void)
+{
+	return persistent_clock_exists;
+}
+
+/**
  * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
  * @delta: pointer to a timespec64 delta value
  *
  * This hook is for architectures that cannot support read_persistent_clock64
  * because their RTC/persistent clock is only accessible when irqs are enabled.
+ * and also don't have an effective nonstop clocksource.
  *
  * This function should only be called by rtc_resume(), and allows
  * a suspend offset to be injected into the timekeeping values.
@@ -1296,13 +1335,6 @@ void timekeeping_inject_sleeptime64(struct timespec64 *delta)
 	struct timekeeper *tk = &tk_core.timekeeper;
 	unsigned long flags;
 
-	/*
-	 * Make sure we don't set the clock twice, as timekeeping_resume()
-	 * already did it
-	 */
-	if (has_persistent_clock())
-		return;
-
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
 
@@ -1334,8 +1366,8 @@ void timekeeping_resume(void)
 	unsigned long flags;
 	struct timespec64 ts_new, ts_delta;
 	cycle_t cycle_now, cycle_delta;
-	bool suspendtime_found = false;
 
+	sleeptime_injected = false;
 	read_persistent_clock64(&ts_new);
 
 	clockevents_resume();
@@ -1381,13 +1413,13 @@ void timekeeping_resume(void)
 		nsec += ((u64) cycle_delta * mult) >> shift;
 
 		ts_delta = ns_to_timespec64(nsec);
-		suspendtime_found = true;
+		sleeptime_injected = true;
 	} else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) {
 		ts_delta = timespec64_sub(ts_new, timekeeping_suspend_time);
-		suspendtime_found = true;
+		sleeptime_injected = true;
 	}
 
-	if (suspendtime_found)
+	if (sleeptime_injected)
 		__timekeeping_inject_sleeptime(tk, &ts_delta);
 
 	/* Re-base the last cycle value */
@@ -1423,14 +1455,14 @@ int timekeeping_suspend(void)
 	 * value returned, update the persistent_clock_exists flag.
 	 */
 	if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec)
-		persistent_clock_exist = true;
+		persistent_clock_exists = true;
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
 	timekeeping_forward_now(tk);
 	timekeeping_suspended = 1;
 
-	if (has_persistent_clock()) {
+	if (persistent_clock_exists) {
 		/*
 		 * To avoid drift caused by repeated suspend/resumes,
 		 * which each can add ~1 second drift error,
-- 
1.9.1


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

* [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (17 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 18/21] time: rtc: Don't bother into rtc_resume() for the nonstop clocksource John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-02  8:50   ` Peter Zijlstra
  2015-04-03  8:20   ` [tip:timers/core] " tip-bot for John Stultz
  2015-04-02  3:34 ` [PATCH 20/21] timekeeping: Change timekeeping_check_update() to take a tk_read_base John Stultz
  2015-04-02  3:34 ` [PATCH 21/21] time: Rework debugging variables so they aren't global John Stultz
  20 siblings, 2 replies; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Ingo Molnar, Thomas Gleixner, Peter Zijlstra,
	Prarit Bhargava, Richard Cochran

Ingo noted that the description of clocks_calc_max_nsecs()'s
50% safety margin was somewhat circular. So this patch tries
to improve the comment to better explain what we mean by the
50% safety margin and why we need it.

Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/clocksource.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index c3be3c7..15facb1 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -472,8 +472,11 @@ static u32 clocksource_max_adjustment(struct clocksource *cs)
  * @max_cyc:	maximum cycle value before potential overflow (does not include
  *		any safety margin)
  *
- * NOTE: This function includes a safety margin of 50%, so that bad clock values
- * can be detected.
+ * NOTE: This function includes a safety margin of 50%, in other words, we
+ * return half the number of nanoseconds the hardware counter can technically
+ * cover. This is done so that we can potentially detect problems caused by
+ * delayed timers or bad hardware, which might result in time intervals that
+ * are larger then what the math used can handle without overflows.
  */
 u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cyc)
 {
-- 
1.9.1


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

* [PATCH 20/21] timekeeping: Change timekeeping_check_update() to take a tk_read_base
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (18 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-02  3:34 ` [PATCH 21/21] time: Rework debugging variables so they aren't global John Stultz
  20 siblings, 0 replies; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Ingo Molnar, Thomas Gleixner, Peter Zijlstra,
	Prarit Bhargava, Richard Cochran

Ingo noted there was no reason to pass the timekeeper structure
to timekeeping_check_update(), and the tk_read_base would be fine,
which simplifies the amount of dereferencing to get to values we
care about.

So this patch simply changes the function as suggested.

Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/timekeeping.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index fe91e8e..676896e 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -131,11 +131,11 @@ static int timekeeping_overflow_seen;
 /* last_warning is only modified under the timekeeping lock */
 static long timekeeping_last_warning;
 
-static void timekeeping_check_update(struct timekeeper *tk, cycle_t offset)
+static void timekeeping_check_update(struct tk_read_base *tkr, cycle_t offset)
 {
 
-	cycle_t max_cycles = tk->tkr_mono.clock->max_cycles;
-	const char *name = tk->tkr_mono.clock->name;
+	cycle_t max_cycles = tkr->clock->max_cycles;
+	const char *name = tkr->clock->name;
 
 	if (offset > max_cycles) {
 		printk_deferred("WARNING: timekeeping: Cycle offset (%lld) is larger than allowed by the '%s' clock's max_cycles value (%lld): time overflow danger\n",
@@ -210,7 +210,7 @@ static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr)
 	return delta;
 }
 #else
-static inline void timekeeping_check_update(struct timekeeper *tk, cycle_t offset)
+static inline void timekeeping_check_update(struct tk_read_base *tkr, cycle_t offset)
 {
 }
 static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr)
@@ -1794,7 +1794,7 @@ void update_wall_time(void)
 		goto out;
 
 	/* Do some additional sanity checking */
-	timekeeping_check_update(real_tk, offset);
+	timekeeping_check_update(&real_tk->tkr_mono, offset);
 
 	/*
 	 * With NO_HZ we may have to accumulate many cycle_intervals
-- 
1.9.1


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

* [PATCH 21/21] time: Rework debugging variables so they aren't global
  2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
                   ` (19 preceding siblings ...)
  2015-04-02  3:34 ` [PATCH 20/21] timekeeping: Change timekeeping_check_update() to take a tk_read_base John Stultz
@ 2015-04-02  3:34 ` John Stultz
  2015-04-02  7:47   ` Peter Zijlstra
  20 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02  3:34 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Ingo Molnar, Thomas Gleixner, Peter Zijlstra,
	Prarit Bhargava, Richard Cochran

Ingo suggested that the timekeeping debugging variables
recently added should not be global, and should be tied
to the timekeeper's read_base.

Thus this patch implements that suggestion.

I'm a little hesitant here, since the tkr structure
has been carefully designed to fit in a cacheline.
However, these additions are all at the end of the
structure and are conditionally compiled.

Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 include/linux/timekeeper_internal.h | 18 +++++++++++++++++-
 kernel/time/timekeeping.c           | 33 ++++++++++-----------------------
 2 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index fb86963..9b33027 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -20,9 +20,13 @@
  * @shift:	Shift value for scaled math conversion
  * @xtime_nsec: Shifted (fractional) nano seconds offset for readout
  * @base:	ktime_t (nanoseconds) base time for readout
+ * @last_warning:   Warning ratelimiter (DEBUG_TIMEKEEPING)
+ * @underflow_seen: Underflow warning flag (DEBUG_TIMEKEEPING)
+ * @overflow_seen:  Overflow warning flag (DEBUG_TIMEKEEPING)
  *
  * This struct has size 56 byte on 64 bit. Together with a seqcount it
- * occupies a single 64byte cache line.
+ * occupies a single 64byte cache line (when DEBUG_TIMEKEEPING is not
+ * enabled).
  *
  * The struct is separate from struct timekeeper as it is also used
  * for a fast NMI safe accessors.
@@ -36,6 +40,18 @@ struct tk_read_base {
 	u32			shift;
 	u64			xtime_nsec;
 	ktime_t			base;
+#ifdef CONFIG_DEBUG_TIMEKEEPING
+	long			last_warning;
+	/*
+	 * These simple flag variables are managed
+	 * without locks, which is racy, but ok since
+	 * we don't really care about being super
+	 * precise about how many events were seen,
+	 * just that a problem was observed.
+	 */
+	int			underflow_seen;
+	int			overflow_seen;
+#endif
 };
 
 /**
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 676896e..ad7a80f 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -118,19 +118,6 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta)
 
 #ifdef CONFIG_DEBUG_TIMEKEEPING
 #define WARNING_FREQ (HZ*300) /* 5 minute rate-limiting */
-/*
- * These simple flag variables are managed
- * without locks, which is racy, but ok since
- * we don't really care about being super
- * precise about how many events were seen,
- * just that a problem was observed.
- */
-static int timekeeping_underflow_seen;
-static int timekeeping_overflow_seen;
-
-/* last_warning is only modified under the timekeeping lock */
-static long timekeeping_last_warning;
-
 static void timekeeping_check_update(struct tk_read_base *tkr, cycle_t offset)
 {
 
@@ -149,24 +136,24 @@ static void timekeeping_check_update(struct tk_read_base *tkr, cycle_t offset)
 		}
 	}
 
-	if (timekeeping_underflow_seen) {
-		if (jiffies - timekeeping_last_warning > WARNING_FREQ) {
+	if (tkr->underflow_seen) {
+		if (jiffies - tkr->last_warning > WARNING_FREQ) {
 			printk_deferred("WARNING: Underflow in clocksource '%s' observed, time update ignored.\n", name);
 			printk_deferred("         Please report this, consider using a different clocksource, if possible.\n");
 			printk_deferred("         Your kernel is probably still fine.\n");
-			timekeeping_last_warning = jiffies;
+			tkr->last_warning = jiffies;
 		}
-		timekeeping_underflow_seen = 0;
+		tkr->underflow_seen = 0;
 	}
 
-	if (timekeeping_overflow_seen) {
-		if (jiffies - timekeeping_last_warning > WARNING_FREQ) {
+	if (tkr->overflow_seen) {
+		if (jiffies - tkr->last_warning > WARNING_FREQ) {
 			printk_deferred("WARNING: Overflow in clocksource '%s' observed, time update capped.\n", name);
 			printk_deferred("         Please report this, consider using a different clocksource, if possible.\n");
 			printk_deferred("         Your kernel is probably still fine.\n");
-			timekeeping_last_warning = jiffies;
+			tkr->last_warning = jiffies;
 		}
-		timekeeping_overflow_seen = 0;
+		tkr->overflow_seen = 0;
 	}
 }
 
@@ -197,13 +184,13 @@ static inline cycle_t timekeeping_get_delta(struct tk_read_base *tkr)
 	 * mask-relative negative values.
 	 */
 	if (unlikely((~delta & mask) < (mask >> 3))) {
-		timekeeping_underflow_seen = 1;
+		tkr->underflow_seen = 1;
 		delta = 0;
 	}
 
 	/* Cap delta value to the max_cycles values to avoid mult overflows */
 	if (unlikely(delta > max)) {
-		timekeeping_overflow_seen = 1;
+		tkr->overflow_seen = 1;
 		delta = tkr->clock->max_cycles;
 	}
 
-- 
1.9.1


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

* Re: [PATCH 21/21] time: Rework debugging variables so they aren't global
  2015-04-02  3:34 ` [PATCH 21/21] time: Rework debugging variables so they aren't global John Stultz
@ 2015-04-02  7:47   ` Peter Zijlstra
  2015-04-02  7:51     ` Ingo Molnar
  0 siblings, 1 reply; 55+ messages in thread
From: Peter Zijlstra @ 2015-04-02  7:47 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Wed, Apr 01, 2015 at 08:34:41PM -0700, John Stultz wrote:
> Ingo suggested that the timekeeping debugging variables
> recently added should not be global, and should be tied
> to the timekeeper's read_base.

But why? its the same hardware clock for both tkr's. Surely if one goes
funny the other will too.

It doesn't make sense to duplicate this.

> I'm a little hesitant here, since the tkr structure
> has been carefully designed to fit in a cacheline.
> However, these additions are all at the end of the
> structure and are conditionally compiled.

That.

>  include/linux/timekeeper_internal.h | 18 +++++++++++++++++-
>  kernel/time/timekeeping.c           | 33 ++++++++++-----------------------
>  2 files changed, 27 insertions(+), 24 deletions(-)
> 
> diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
> index fb86963..9b33027 100644
> --- a/include/linux/timekeeper_internal.h
> +++ b/include/linux/timekeeper_internal.h
> @@ -20,9 +20,13 @@
>   * @shift:	Shift value for scaled math conversion
>   * @xtime_nsec: Shifted (fractional) nano seconds offset for readout
>   * @base:	ktime_t (nanoseconds) base time for readout
> + * @last_warning:   Warning ratelimiter (DEBUG_TIMEKEEPING)
> + * @underflow_seen: Underflow warning flag (DEBUG_TIMEKEEPING)
> + * @overflow_seen:  Overflow warning flag (DEBUG_TIMEKEEPING)
>   *
>   * This struct has size 56 byte on 64 bit. Together with a seqcount it
> - * occupies a single 64byte cache line.
> + * occupies a single 64byte cache line (when DEBUG_TIMEKEEPING is not
> + * enabled).
>   *
>   * The struct is separate from struct timekeeper as it is also used
>   * for a fast NMI safe accessors.
> @@ -36,6 +40,18 @@ struct tk_read_base {
>  	u32			shift;
>  	u64			xtime_nsec;
>  	ktime_t			base;
> +#ifdef CONFIG_DEBUG_TIMEKEEPING
> +	long			last_warning;
> +	/*
> +	 * These simple flag variables are managed
> +	 * without locks, which is racy, but ok since
> +	 * we don't really care about being super
> +	 * precise about how many events were seen,
> +	 * just that a problem was observed.
> +	 */
> +	int			underflow_seen;
> +	int			overflow_seen;
> +#endif
>  };

Yeah, so what is the likelyhood of a distro blanked enabling that debug?

I really don't like this much.

Also, you're now lacking a call to timekeeping_check_update(&tkr_raw),
you update stats there but have no way to report on them.

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

* Re: [PATCH 21/21] time: Rework debugging variables so they aren't global
  2015-04-02  7:47   ` Peter Zijlstra
@ 2015-04-02  7:51     ` Ingo Molnar
  2015-04-02  8:36       ` Peter Zijlstra
  2015-04-02 17:32       ` John Stultz
  0 siblings, 2 replies; 55+ messages in thread
From: Ingo Molnar @ 2015-04-02  7:51 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: John Stultz, lkml, Thomas Gleixner, Prarit Bhargava, Richard Cochran


* Peter Zijlstra <peterz@infradead.org> wrote:

> On Wed, Apr 01, 2015 at 08:34:41PM -0700, John Stultz wrote:
> > Ingo suggested that the timekeeping debugging variables
> > recently added should not be global, and should be tied
> > to the timekeeper's read_base.
> 
> But why? its the same hardware clock for both tkr's. Surely if one goes
> funny the other will too.
> 
> It doesn't make sense to duplicate this.

Well, could it be moved to the timekeeper data structure? What I was 
opposed to was making it super-global, after all the (nice) effort we 
made to tidy up global data structures in this area.

Thanks,

	Ingo

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

* Re: [PATCH 21/21] time: Rework debugging variables so they aren't global
  2015-04-02  7:51     ` Ingo Molnar
@ 2015-04-02  8:36       ` Peter Zijlstra
  2015-04-02  8:41         ` Peter Zijlstra
  2015-04-02 17:32       ` John Stultz
  1 sibling, 1 reply; 55+ messages in thread
From: Peter Zijlstra @ 2015-04-02  8:36 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: John Stultz, lkml, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 02, 2015 at 09:51:51AM +0200, Ingo Molnar wrote:
> 
> * Peter Zijlstra <peterz@infradead.org> wrote:
> 
> > On Wed, Apr 01, 2015 at 08:34:41PM -0700, John Stultz wrote:
> > > Ingo suggested that the timekeeping debugging variables
> > > recently added should not be global, and should be tied
> > > to the timekeeper's read_base.
> > 
> > But why? its the same hardware clock for both tkr's. Surely if one goes
> > funny the other will too.
> > 
> > It doesn't make sense to duplicate this.
> 
> Well, could it be moved to the timekeeper data structure? What I was 
> opposed to was making it super-global, after all the (nice) effort we 
> made to tidy up global data structures in this area.

Sure, struct timekeeper would work, the debug code already references
the global tk_core to access that.

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

* Re: [PATCH 21/21] time: Rework debugging variables so they aren't global
  2015-04-02  8:36       ` Peter Zijlstra
@ 2015-04-02  8:41         ` Peter Zijlstra
  0 siblings, 0 replies; 55+ messages in thread
From: Peter Zijlstra @ 2015-04-02  8:41 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: John Stultz, lkml, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 02, 2015 at 10:36:47AM +0200, Peter Zijlstra wrote:
> Sure, struct timekeeper would work, the debug code already references
> the global tk_core to access that.

While looking at that, the comment near tk_core says:

/*
 * The most important data for readout fits into a single 64 byte
 * cache line.
 */

I feel that should be qualified somewhat, this is only true for
MONOTONIC (ktime_get()), any other time base ends up on more lines.

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

* Re: [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02  3:34 ` [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin John Stultz
@ 2015-04-02  8:50   ` Peter Zijlstra
  2015-04-02 17:30     ` John Stultz
  2015-04-03  8:20   ` [tip:timers/core] " tip-bot for John Stultz
  1 sibling, 1 reply; 55+ messages in thread
From: Peter Zijlstra @ 2015-04-02  8:50 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Wed, Apr 01, 2015 at 08:34:39PM -0700, John Stultz wrote:
> Ingo noted that the description of clocks_calc_max_nsecs()'s
> 50% safety margin was somewhat circular. So this patch tries
> to improve the comment to better explain what we mean by the
> 50% safety margin and why we need it.
> 
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Prarit Bhargava <prarit@redhat.com>
> Cc: Richard Cochran <richardcochran@gmail.com>
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
>  kernel/time/clocksource.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
> index c3be3c7..15facb1 100644
> --- a/kernel/time/clocksource.c
> +++ b/kernel/time/clocksource.c
> @@ -472,8 +472,11 @@ static u32 clocksource_max_adjustment(struct clocksource *cs)
>   * @max_cyc:	maximum cycle value before potential overflow (does not include
>   *		any safety margin)
>   *
> - * NOTE: This function includes a safety margin of 50%, so that bad clock values
> - * can be detected.
> + * NOTE: This function includes a safety margin of 50%, in other words, we
> + * return half the number of nanoseconds the hardware counter can technically
> + * cover. This is done so that we can potentially detect problems caused by
> + * delayed timers or bad hardware, which might result in time intervals that
> + * are larger then what the math used can handle without overflows.
>   */
>  u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cyc)
>  {

Should we make a further note that the tk_fast things rely on this
slack since they're not strongly serialized against this? That is, they
can end up using an older cycle_last value and therefore end up with a
larger delta than other code.

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

* Re: [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02  8:50   ` Peter Zijlstra
@ 2015-04-02 17:30     ` John Stultz
  2015-04-02 18:34       ` Peter Zijlstra
  0 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02 17:30 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 2, 2015 at 1:50 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Wed, Apr 01, 2015 at 08:34:39PM -0700, John Stultz wrote:
>> Ingo noted that the description of clocks_calc_max_nsecs()'s
>> 50% safety margin was somewhat circular. So this patch tries
>> to improve the comment to better explain what we mean by the
>> 50% safety margin and why we need it.
>>
>> Cc: Ingo Molnar <mingo@kernel.org>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Peter Zijlstra <peterz@infradead.org>
>> Cc: Prarit Bhargava <prarit@redhat.com>
>> Cc: Richard Cochran <richardcochran@gmail.com>
>> Signed-off-by: John Stultz <john.stultz@linaro.org>
>> ---
>>  kernel/time/clocksource.c | 7 +++++--
>>  1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
>> index c3be3c7..15facb1 100644
>> --- a/kernel/time/clocksource.c
>> +++ b/kernel/time/clocksource.c
>> @@ -472,8 +472,11 @@ static u32 clocksource_max_adjustment(struct clocksource *cs)
>>   * @max_cyc: maximum cycle value before potential overflow (does not include
>>   *           any safety margin)
>>   *
>> - * NOTE: This function includes a safety margin of 50%, so that bad clock values
>> - * can be detected.
>> + * NOTE: This function includes a safety margin of 50%, in other words, we
>> + * return half the number of nanoseconds the hardware counter can technically
>> + * cover. This is done so that we can potentially detect problems caused by
>> + * delayed timers or bad hardware, which might result in time intervals that
>> + * are larger then what the math used can handle without overflows.
>>   */
>>  u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cyc)
>>  {
>
> Should we make a further note that the tk_fast things rely on this
> slack since they're not strongly serialized against this? That is, they
> can end up using an older cycle_last value and therefore end up with a
> larger delta than other code.

Though, even with the tk_fast bits, we expect the update to happen
regularly, its just that for the benefit of lock-free access we are ok
with the possible slight inconsistencies (in the mono clock) that
could happen if we use a slightly stale value mid-update. So I don't
think the tk_fast bits are actually relying on the slack any more then
the normal timekeeping code relies on the slack to handle slight
delays in processing the updates.  If we deal with time deltas large
enough to cause overflows, or time intervals larger then the hardware
can represent, we're sunk in either case. This 50% margin just makes
it easier to catch unexpected delays or issues.

thanks
-john

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

* Re: [PATCH 21/21] time: Rework debugging variables so they aren't global
  2015-04-02  7:51     ` Ingo Molnar
  2015-04-02  8:36       ` Peter Zijlstra
@ 2015-04-02 17:32       ` John Stultz
  2015-04-03  6:21         ` Ingo Molnar
  1 sibling, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02 17:32 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, lkml, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 2, 2015 at 12:51 AM, Ingo Molnar <mingo@kernel.org> wrote:
>
> * Peter Zijlstra <peterz@infradead.org> wrote:
>
>> On Wed, Apr 01, 2015 at 08:34:41PM -0700, John Stultz wrote:
>> > Ingo suggested that the timekeeping debugging variables
>> > recently added should not be global, and should be tied
>> > to the timekeeper's read_base.
>>
>> But why? its the same hardware clock for both tkr's. Surely if one goes
>> funny the other will too.
>>
>> It doesn't make sense to duplicate this.
>
> Well, could it be moved to the timekeeper data structure? What I was
> opposed to was making it super-global, after all the (nice) effort we
> made to tidy up global data structures in this area.

Ok. I'll rework this then and resend.  Though if there's no objections
to Xunlei's portion of the series, would you mind merging those into
-tip? I'd like to make sure they get some time in -next before the
merge window opens.

thanks
-john

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

* Re: [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02 17:30     ` John Stultz
@ 2015-04-02 18:34       ` Peter Zijlstra
  2015-04-02 18:41         ` John Stultz
  0 siblings, 1 reply; 55+ messages in thread
From: Peter Zijlstra @ 2015-04-02 18:34 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 02, 2015 at 10:30:18AM -0700, John Stultz wrote:
> > Should we make a further note that the tk_fast things rely on this
> > slack since they're not strongly serialized against this? That is, they
> > can end up using an older cycle_last value and therefore end up with a
> > larger delta than other code.
> 
> Though, even with the tk_fast bits, we expect the update to happen
> regularly, its just that for the benefit of lock-free access we are ok
> with the possible slight inconsistencies (in the mono clock) that
> could happen if we use a slightly stale value mid-update. So I don't
> think the tk_fast bits are actually relying on the slack any more then
> the normal timekeeping code relies on the slack to handle slight
> delays in processing the updates.  If we deal with time deltas large
> enough to cause overflows, or time intervals larger then the hardware
> can represent, we're sunk in either case. This 50% margin just makes
> it easier to catch unexpected delays or issues.

Right, so you're saying that even though the fast bits will see slightly
larger deltas than the normal code, they should still not get anywhere
near the 50% because we update much more frequently?

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

* Re: [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02 18:34       ` Peter Zijlstra
@ 2015-04-02 18:41         ` John Stultz
  2015-04-02 18:43           ` Peter Zijlstra
  0 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02 18:41 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 2, 2015 at 11:34 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Thu, Apr 02, 2015 at 10:30:18AM -0700, John Stultz wrote:
>> > Should we make a further note that the tk_fast things rely on this
>> > slack since they're not strongly serialized against this? That is, they
>> > can end up using an older cycle_last value and therefore end up with a
>> > larger delta than other code.
>>
>> Though, even with the tk_fast bits, we expect the update to happen
>> regularly, its just that for the benefit of lock-free access we are ok
>> with the possible slight inconsistencies (in the mono clock) that
>> could happen if we use a slightly stale value mid-update. So I don't
>> think the tk_fast bits are actually relying on the slack any more then
>> the normal timekeeping code relies on the slack to handle slight
>> delays in processing the updates.  If we deal with time deltas large
>> enough to cause overflows, or time intervals larger then the hardware
>> can represent, we're sunk in either case. This 50% margin just makes
>> it easier to catch unexpected delays or issues.
>
> Right, so you're saying that even though the fast bits will see slightly
> larger deltas than the normal code, they should still not get anywhere
> near the 50% because we update much more frequently?

Well, they may get to 50% or slightly over (since 50% is the max nohz
idle length), but that's likely rare, and we shouldn't get anywhere
close to real failure edges (100% be it the mult-overflow or hardware
mask limit).

thanks
-john

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

* Re: [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02 18:41         ` John Stultz
@ 2015-04-02 18:43           ` Peter Zijlstra
  2015-04-02 18:50             ` John Stultz
  0 siblings, 1 reply; 55+ messages in thread
From: Peter Zijlstra @ 2015-04-02 18:43 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 02, 2015 at 11:41:15AM -0700, John Stultz wrote:
> On Thu, Apr 2, 2015 at 11:34 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> > On Thu, Apr 02, 2015 at 10:30:18AM -0700, John Stultz wrote:
> >> > Should we make a further note that the tk_fast things rely on this
> >> > slack since they're not strongly serialized against this? That is, they
> >> > can end up using an older cycle_last value and therefore end up with a
> >> > larger delta than other code.
> >>
> >> Though, even with the tk_fast bits, we expect the update to happen
> >> regularly, its just that for the benefit of lock-free access we are ok
> >> with the possible slight inconsistencies (in the mono clock) that
> >> could happen if we use a slightly stale value mid-update. So I don't
> >> think the tk_fast bits are actually relying on the slack any more then
> >> the normal timekeeping code relies on the slack to handle slight
> >> delays in processing the updates.  If we deal with time deltas large
> >> enough to cause overflows, or time intervals larger then the hardware
> >> can represent, we're sunk in either case. This 50% margin just makes
> >> it easier to catch unexpected delays or issues.
> >
> > Right, so you're saying that even though the fast bits will see slightly
> > larger deltas than the normal code, they should still not get anywhere
> > near the 50% because we update much more frequently?
> 
> Well, they may get to 50% or slightly over (since 50% is the max nohz
> idle length), but that's likely rare, and we shouldn't get anywhere
> close to real failure edges (100% be it the mult-overflow or hardware
> mask limit).

Right, so the fast thing rely on there being slack. That was my point
rather. I know they'll not get to the end of slack.

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

* Re: [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02 18:43           ` Peter Zijlstra
@ 2015-04-02 18:50             ` John Stultz
  2015-04-02 19:04               ` Peter Zijlstra
  0 siblings, 1 reply; 55+ messages in thread
From: John Stultz @ 2015-04-02 18:50 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 2, 2015 at 11:43 AM, Peter Zijlstra <peterz@infradead.org> wrote:
> On Thu, Apr 02, 2015 at 11:41:15AM -0700, John Stultz wrote:
>> On Thu, Apr 2, 2015 at 11:34 AM, Peter Zijlstra <peterz@infradead.org> wrote:
>> > On Thu, Apr 02, 2015 at 10:30:18AM -0700, John Stultz wrote:
>> >> > Should we make a further note that the tk_fast things rely on this
>> >> > slack since they're not strongly serialized against this? That is, they
>> >> > can end up using an older cycle_last value and therefore end up with a
>> >> > larger delta than other code.
>> >>
>> >> Though, even with the tk_fast bits, we expect the update to happen
>> >> regularly, its just that for the benefit of lock-free access we are ok
>> >> with the possible slight inconsistencies (in the mono clock) that
>> >> could happen if we use a slightly stale value mid-update. So I don't
>> >> think the tk_fast bits are actually relying on the slack any more then
>> >> the normal timekeeping code relies on the slack to handle slight
>> >> delays in processing the updates.  If we deal with time deltas large
>> >> enough to cause overflows, or time intervals larger then the hardware
>> >> can represent, we're sunk in either case. This 50% margin just makes
>> >> it easier to catch unexpected delays or issues.
>> >
>> > Right, so you're saying that even though the fast bits will see slightly
>> > larger deltas than the normal code, they should still not get anywhere
>> > near the 50% because we update much more frequently?
>>
>> Well, they may get to 50% or slightly over (since 50% is the max nohz
>> idle length), but that's likely rare, and we shouldn't get anywhere
>> close to real failure edges (100% be it the mult-overflow or hardware
>> mask limit).
>
> Right, so the fast thing rely on there being slack. That was my point
> rather. I know they'll not get to the end of slack.

Right, but all of the time code relies on there being slack, since we
can't be sure timers will not be slightly late.
For the fast-timekeper stuff, its just that the deltas could be ever
so slightly larger since the lock-free reads can land during an
update. Its not that its ok for the update to be delayed longer for
fast-timekeepers, or that we expect them to handle larger deltas then
the normal time read logic can handle.

thanks
-john

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

* Re: [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02 18:50             ` John Stultz
@ 2015-04-02 19:04               ` Peter Zijlstra
  0 siblings, 0 replies; 55+ messages in thread
From: Peter Zijlstra @ 2015-04-02 19:04 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Ingo Molnar, Thomas Gleixner, Prarit Bhargava, Richard Cochran

On Thu, Apr 02, 2015 at 11:50:13AM -0700, John Stultz wrote:
> 
> Right, but all of the time code relies on there being slack, since we
> can't be sure timers will not be slightly late.

Fair enough. My point is moot, I'll go crawl back into my cave ;-)

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

* Re: [PATCH 17/21] time: Fix a bug in timekeeping_suspend() with no persistent clock
  2015-04-02  3:34 ` [PATCH 17/21] time: Fix a bug in timekeeping_suspend() with no persistent clock John Stultz
@ 2015-04-03  6:16   ` Ingo Molnar
  2015-04-03  8:20   ` [tip:timers/core] " tip-bot for Xunlei Pang
  1 sibling, 0 replies; 55+ messages in thread
From: Ingo Molnar @ 2015-04-03  6:16 UTC (permalink / raw)
  To: John Stultz; +Cc: lkml, Xunlei Pang, Peter Zijlstra, Thomas Gleixner


* John Stultz <john.stultz@linaro.org> wrote:

> From: Xunlei Pang <pang.xunlei@linaro.org>
> 
> When there's no persistent clock, normally timekeeping_suspend_time
> should always be zero, but this can break in timekeeping_suspend().
> 
> At T1, there was a system suspend, so old_delta was assigned T1.
> After some time, one time adjustment happened, and xtime got the
> value of T1-dt(0s<dt<2s). Then, there comes another system suspend
> soon after this adjustment, obviously we will get a small negative
> delta_delta, resulting in a negative timekeeping_suspend_time.
> 
> This is problematic, when doing timekeeping_resume() if there is
> no nonstop clocksource for example, it will hit the else leg and
> inject the improper sleeptime which is the wrong logic.
> 
> So, we can solve this problem by only doing delta related code when
> the persistent clock is existent. Actually the code only makes sense
> for persistent clock cases.

What's the effect in practice of such negative delta_delta values? 
What kind of effects would users see from this?

Thanks,

	Ingo

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

* Re: [PATCH 21/21] time: Rework debugging variables so they aren't global
  2015-04-02 17:32       ` John Stultz
@ 2015-04-03  6:21         ` Ingo Molnar
  0 siblings, 0 replies; 55+ messages in thread
From: Ingo Molnar @ 2015-04-03  6:21 UTC (permalink / raw)
  To: John Stultz
  Cc: Peter Zijlstra, lkml, Thomas Gleixner, Prarit Bhargava, Richard Cochran


* John Stultz <john.stultz@linaro.org> wrote:

> On Thu, Apr 2, 2015 at 12:51 AM, Ingo Molnar <mingo@kernel.org> wrote:
> >
> > * Peter Zijlstra <peterz@infradead.org> wrote:
> >
> >> On Wed, Apr 01, 2015 at 08:34:41PM -0700, John Stultz wrote:
> >> > Ingo suggested that the timekeeping debugging variables
> >> > recently added should not be global, and should be tied
> >> > to the timekeeper's read_base.
> >>
> >> But why? its the same hardware clock for both tkr's. Surely if one goes
> >> funny the other will too.
> >>
> >> It doesn't make sense to duplicate this.
> >
> > Well, could it be moved to the timekeeper data structure? What I was
> > opposed to was making it super-global, after all the (nice) effort we
> > made to tidy up global data structures in this area.
> 
> Ok. I'll rework this then and resend.  Though if there's no objections
> to Xunlei's portion of the series, would you mind merging those into
> -tip? I'd like to make sure they get some time in -next before the
> merge window opens.

Yeah, it all looks good to me, I've picked up all but this one patch 
from your series and will push it out once it has gone through 
testing.

I updated some of the titles and changelogs and added a few more Cc:s 
where it seemed appropriate.

Thanks,

	Ingo

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

* [tip:timers/core] time: Add y2038 safe read_boot_clock64()
  2015-04-02  3:34 ` [PATCH 01/21] time: Add y2038 safe read_boot_clock64() John Stultz
@ 2015-04-03  8:15   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, tglx, pang.xunlei, arnd, hpa, john.stultz, mingo, peterz

Commit-ID:  9a806ddbb9a18c510e4acdcc828b9a87f5fd3aef
Gitweb:     http://git.kernel.org/tip/9a806ddbb9a18c510e4acdcc828b9a87f5fd3aef
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:21 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:18 +0200

time: Add y2038 safe read_boot_clock64()

As part of addressing in-kernel y2038 issues, this patch adds
read_boot_clock64() and replaces all the call sites of
read_boot_clock() with this function. This is a __weak
implementation, which simply calls the existing y2038 unsafe
read_boot_clock().

This allows architecture specific implementations to be
converted independently, and eventually the y2038 unsafe
read_boot_clock() can be removed after all its architecture
specific implementations have been converted to
read_boot_clock64().

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-2-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 include/linux/timekeeping.h |  1 +
 kernel/time/timekeeping.c   | 11 +++++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 5047b83..18d27a3 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -269,6 +269,7 @@ static inline bool has_persistent_clock(void)
 
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_boot_clock(struct timespec *ts);
+extern void read_boot_clock64(struct timespec64 *ts);
 extern int update_persistent_clock(struct timespec now);
 
 
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 5b12292..652e50a 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1188,6 +1188,14 @@ void __weak read_boot_clock(struct timespec *ts)
 	ts->tv_nsec = 0;
 }
 
+void __weak read_boot_clock64(struct timespec64 *ts64)
+{
+	struct timespec ts;
+
+	read_boot_clock(&ts);
+	*ts64 = timespec_to_timespec64(ts);
+}
+
 /*
  * timekeeping_init - Initializes the clocksource and common timekeeping values
  */
@@ -1209,8 +1217,7 @@ void __init timekeeping_init(void)
 	} else if (now.tv_sec || now.tv_nsec)
 		persistent_clock_exist = true;
 
-	read_boot_clock(&ts);
-	boot = timespec_to_timespec64(ts);
+	read_boot_clock64(&boot);
 	if (!timespec64_valid_strict(&boot)) {
 		pr_warn("WARNING: Boot clock returned invalid value!\n"
 			"         Check your CMOS/BIOS settings.\n");

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

* [tip:timers/core] time: Add y2038 safe read_persistent_clock64()
  2015-04-02  3:34 ` [PATCH 02/21] time: Add y2038 safe read_persistent_clock64() John Stultz
@ 2015-04-03  8:15   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:15 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, john.stultz, peterz, hpa, pang.xunlei, tglx, arnd, mingo

Commit-ID:  2ee966320028ac846654eba5344540eeb4dc228d
Gitweb:     http://git.kernel.org/tip/2ee966320028ac846654eba5344540eeb4dc228d
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:22 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:19 +0200

time: Add y2038 safe read_persistent_clock64()

As part of addressing in-kernel y2038 issues, this patch adds
read_persistent_clock64() and replaces all the call sites of
read_persistent_clock() with this function. This is a __weak
implementation, which simply calls the existing y2038 unsafe
read_persistent_clock().

This allows architecture specific implementations to be
converted independently, and eventually the y2038 unsafe
read_persistent_clock() can be removed after all its
architecture specific implementations have been converted to
read_persistent_clock64().

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-3-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/mips/lasat/sysctl.c    |  4 ++--
 include/linux/timekeeping.h |  1 +
 kernel/time/timekeeping.c   | 22 ++++++++++++----------
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
index 3b7f65c..cf9b4633 100644
--- a/arch/mips/lasat/sysctl.c
+++ b/arch/mips/lasat/sysctl.c
@@ -75,11 +75,11 @@ static int rtctmp;
 int proc_dolasatrtc(struct ctl_table *table, int write,
 		       void *buffer, size_t *lenp, loff_t *ppos)
 {
-	struct timespec ts;
+	struct timespec64 ts;
 	int r;
 
 	if (!write) {
-		read_persistent_clock(&ts);
+		read_persistent_clock64(&ts);
 		rtctmp = ts.tv_sec;
 		/* check for time < 0 and set to 0 */
 		if (rtctmp < 0)
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 18d27a3..4c0f76f 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -268,6 +268,7 @@ static inline bool has_persistent_clock(void)
 }
 
 extern void read_persistent_clock(struct timespec *ts);
+extern void read_persistent_clock64(struct timespec64 *ts);
 extern void read_boot_clock(struct timespec *ts);
 extern void read_boot_clock64(struct timespec64 *ts);
 extern int update_persistent_clock(struct timespec now);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 652e50a..b1dbfa5 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1173,6 +1173,14 @@ void __weak read_persistent_clock(struct timespec *ts)
 	ts->tv_nsec = 0;
 }
 
+void __weak read_persistent_clock64(struct timespec64 *ts64)
+{
+	struct timespec ts;
+
+	read_persistent_clock(&ts);
+	*ts64 = timespec_to_timespec64(ts);
+}
+
 /**
  * read_boot_clock -  Return time of the system start.
  *
@@ -1205,10 +1213,8 @@ void __init timekeeping_init(void)
 	struct clocksource *clock;
 	unsigned long flags;
 	struct timespec64 now, boot, tmp;
-	struct timespec ts;
 
-	read_persistent_clock(&ts);
-	now = timespec_to_timespec64(ts);
+	read_persistent_clock64(&now);
 	if (!timespec64_valid_strict(&now)) {
 		pr_warn("WARNING: Persistent clock returned invalid value!\n"
 			"         Check your CMOS/BIOS settings.\n");
@@ -1278,7 +1284,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
  * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
  * @delta: pointer to a timespec64 delta value
  *
- * This hook is for architectures that cannot support read_persistent_clock
+ * This hook is for architectures that cannot support read_persistent_clock64
  * because their RTC/persistent clock is only accessible when irqs are enabled.
  *
  * This function should only be called by rtc_resume(), and allows
@@ -1325,12 +1331,10 @@ void timekeeping_resume(void)
 	struct clocksource *clock = tk->tkr_mono.clock;
 	unsigned long flags;
 	struct timespec64 ts_new, ts_delta;
-	struct timespec tmp;
 	cycle_t cycle_now, cycle_delta;
 	bool suspendtime_found = false;
 
-	read_persistent_clock(&tmp);
-	ts_new = timespec_to_timespec64(tmp);
+	read_persistent_clock64(&ts_new);
 
 	clockevents_resume();
 	clocksource_resume();
@@ -1406,10 +1410,8 @@ int timekeeping_suspend(void)
 	unsigned long flags;
 	struct timespec64		delta, delta_delta;
 	static struct timespec64	old_delta;
-	struct timespec tmp;
 
-	read_persistent_clock(&tmp);
-	timekeeping_suspend_time = timespec_to_timespec64(tmp);
+	read_persistent_clock64(&timekeeping_suspend_time);
 
 	/*
 	 * On some systems the persistent_clock can not be detected at

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

* [tip:timers/core] time: Add y2038 safe update_persistent_clock64( )
  2015-04-02  3:34 ` [PATCH 03/21] time: Add y2038 safe update_persistent_clock64() John Stultz
@ 2015-04-03  8:16   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, mingo, pang.xunlei, tglx, arnd, john.stultz, hpa, peterz

Commit-ID:  3c00a1fe8496ff29ab62764bb3f4ce4b48089004
Gitweb:     http://git.kernel.org/tip/3c00a1fe8496ff29ab62764bb3f4ce4b48089004
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:23 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:20 +0200

time: Add y2038 safe update_persistent_clock64()

As part of addressing in-kernel y2038 issues, this patch adds
update_persistent_clock64() and replaces all the call sites of
update_persistent_clock() with this function. This is a __weak
implementation, which simply calls the existing y2038 unsafe
update_persistent_clock().

This allows architecture specific implementations to be
converted independently, and eventually y2038-unsafe
update_persistent_clock() can be removed after all its
architecture specific implementations have been converted to
update_persistent_clock64().

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-4-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/systohc.c       |  2 +-
 include/linux/timekeeping.h |  1 +
 kernel/time/ntp.c           | 13 ++++++++++++-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
index eb71872..ef3c07a 100644
--- a/drivers/rtc/systohc.c
+++ b/drivers/rtc/systohc.c
@@ -11,7 +11,7 @@
  * rtc_set_ntp_time - Save NTP synchronized time to the RTC
  * @now: Current time of day
  *
- * Replacement for the NTP platform function update_persistent_clock
+ * Replacement for the NTP platform function update_persistent_clock64
  * that stores time for later retrieval by rtc_hctosys.
  *
  * Returns 0 on successful RTC update, -ENODEV if a RTC update is not
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 4c0f76f..7a2369d 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -272,6 +272,7 @@ extern void read_persistent_clock64(struct timespec64 *ts);
 extern void read_boot_clock(struct timespec *ts);
 extern void read_boot_clock64(struct timespec64 *ts);
 extern int update_persistent_clock(struct timespec now);
+extern int update_persistent_clock64(struct timespec64 now);
 
 
 #endif
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 9ad60d0..7a68100 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -458,6 +458,16 @@ out:
 	return leap;
 }
 
+#ifdef CONFIG_GENERIC_CMOS_UPDATE
+int __weak update_persistent_clock64(struct timespec64 now64)
+{
+	struct timespec now;
+
+	now = timespec64_to_timespec(now64);
+	return update_persistent_clock(now);
+}
+#endif
+
 #if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC)
 static void sync_cmos_clock(struct work_struct *work);
 
@@ -493,8 +503,9 @@ static void sync_cmos_clock(struct work_struct *work)
 		if (persistent_clock_is_local)
 			adjust.tv_sec -= (sys_tz.tz_minuteswest * 60);
 #ifdef CONFIG_GENERIC_CMOS_UPDATE
-		fail = update_persistent_clock(timespec64_to_timespec(adjust));
+		fail = update_persistent_clock64(adjust);
 #endif
+
 #ifdef CONFIG_RTC_SYSTOHC
 		if (fail == -ENODEV)
 			fail = rtc_set_ntp_time(adjust);

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

* [tip:timers/core] ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement
  2015-04-02  3:34 ` [PATCH 04/21] ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement John Stultz
@ 2015-04-03  8:16   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, mingo, pang.xunlei, tony, linux-kernel, hpa, peterz, john.stultz

Commit-ID:  a451570c008b9e19592e29f15cfd295bdf818c7a
Gitweb:     http://git.kernel.org/tip/a451570c008b9e19592e29f15cfd295bdf818c7a
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:24 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:21 +0200

ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement

As part of addressing "y2038 problem" for in-kernel uses, this
patch adds the y2038-safe omap_read_persistent_clock64() using
timespec64.

Because we rely on some subsequent changes to convert arm
multiarch support, omap_read_persistent_clock() will be removed
then.

Also remove the needless spinlock, because
read_persistent_clock() doesn't run simultaneously.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Tony Lindgren <tony@atomide.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-5-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm/plat-omap/counter_32k.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 43cf745..b7b7b07 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -44,24 +44,20 @@ static u64 notrace omap_32k_read_sched_clock(void)
 }
 
 /**
- * omap_read_persistent_clock -  Return time from a persistent clock.
+ * omap_read_persistent_clock64 -  Return time from a persistent clock.
  *
  * Reads the time from a source which isn't disabled during PM, the
  * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec.
+ * nsecs and adds to a monotonically increasing timespec64.
  */
-static struct timespec persistent_ts;
+static struct timespec64 persistent_ts;
 static cycles_t cycles;
 static unsigned int persistent_mult, persistent_shift;
-static DEFINE_SPINLOCK(read_persistent_clock_lock);
 
-static void omap_read_persistent_clock(struct timespec *ts)
+static void omap_read_persistent_clock64(struct timespec64 *ts)
 {
 	unsigned long long nsecs;
 	cycles_t last_cycles;
-	unsigned long flags;
-
-	spin_lock_irqsave(&read_persistent_clock_lock, flags);
 
 	last_cycles = cycles;
 	cycles = sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0;
@@ -69,11 +65,17 @@ static void omap_read_persistent_clock(struct timespec *ts)
 	nsecs = clocksource_cyc2ns(cycles - last_cycles,
 					persistent_mult, persistent_shift);
 
-	timespec_add_ns(&persistent_ts, nsecs);
+	timespec64_add_ns(&persistent_ts, nsecs);
 
 	*ts = persistent_ts;
+}
+
+static void omap_read_persistent_clock(struct timespec *ts)
+{
+	struct timespec64 ts64;
 
-	spin_unlock_irqrestore(&read_persistent_clock_lock, flags);
+	omap_read_persistent_clock64(&ts64);
+	*ts = timespec64_to_timespec(ts64);
 }
 
 /**

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

* [tip:timers/core] clocksource/drivers/tegra: Provide y2038-safe tegra_read_persistent_clock() replacement
  2015-04-02  3:34 ` [PATCH 05/21] ARM: tegra: clock: Provide y2038-safe tegra_read_persistent_clock() replacement John Stultz
@ 2015-04-03  8:16   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:16 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, peterz, mingo, pang.xunlei, tglx, john.stultz, treding,
	linux-kernel

Commit-ID:  a0c2998f918e7e597d3c686c5f3d5a30d0382dd6
Gitweb:     http://git.kernel.org/tip/a0c2998f918e7e597d3c686c5f3d5a30d0382dd6
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:25 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:22 +0200

clocksource/drivers/tegra: Provide y2038-safe tegra_read_persistent_clock() replacement

As part of addressing "y2038 problem" for in-kernel uses, this
patch adds the y2038-safe tegra_read_persistent_clock64() using
timespec64.

Because we rely on some subsequent changes to convert arm
multiarch support, tegra_read_persistent_clock() will be removed
then.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Thierry Reding <treding@nvidia.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-6-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/clocksource/tegra20_timer.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c
index d8a3a4e..4a0a603 100644
--- a/drivers/clocksource/tegra20_timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -51,7 +51,7 @@
 static void __iomem *timer_reg_base;
 static void __iomem *rtc_base;
 
-static struct timespec persistent_ts;
+static struct timespec64 persistent_ts;
 static u64 persistent_ms, last_persistent_ms;
 
 static struct delay_timer tegra_delay_timer;
@@ -120,26 +120,33 @@ static u64 tegra_rtc_read_ms(void)
 }
 
 /*
- * tegra_read_persistent_clock -  Return time from a persistent clock.
+ * tegra_read_persistent_clock64 -  Return time from a persistent clock.
  *
  * Reads the time from a source which isn't disabled during PM, the
  * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec.
+ * nsecs and adds to a monotonically increasing timespec64.
  * Care must be taken that this funciton is not called while the
  * tegra_rtc driver could be executing to avoid race conditions
  * on the RTC shadow register
  */
-static void tegra_read_persistent_clock(struct timespec *ts)
+static void tegra_read_persistent_clock64(struct timespec64 *ts)
 {
 	u64 delta;
-	struct timespec *tsp = &persistent_ts;
 
 	last_persistent_ms = persistent_ms;
 	persistent_ms = tegra_rtc_read_ms();
 	delta = persistent_ms - last_persistent_ms;
 
-	timespec_add_ns(tsp, delta * NSEC_PER_MSEC);
-	*ts = *tsp;
+	timespec64_add_ns(&persistent_ts, delta * NSEC_PER_MSEC);
+	*ts = persistent_ts;
+}
+
+static void tegra_read_persistent_clock(struct timespec *ts)
+{
+	struct timespec ts64;
+
+	tegra_read_persistent_clock64(&ts64);
+	*ts = timespec64_to_timespec(ts64);
 }
 
 static unsigned long tegra_delay_timer_read_counter_long(void)

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

* [tip:timers/core] ARM, clocksource/drivers: Provide read_boot_clock64() and read_persistent_clock64() and use them
  2015-04-02  3:34 ` [PATCH 06/21] ARM: time: Provide read_boot_clock64() and read_persistent_clock64() John Stultz
@ 2015-04-03  8:17   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, linux-kernel, peterz, mingo, pang.xunlei, rmk, john.stultz, tglx

Commit-ID:  cb850717b076d979058d52529e15f1736359d811
Gitweb:     http://git.kernel.org/tip/cb850717b076d979058d52529e15f1736359d811
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:26 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:23 +0200

ARM, clocksource/drivers: Provide read_boot_clock64() and read_persistent_clock64() and use them

As part of addressing "y2038 problem" for in-kernel uses, this
patch converts read_boot_clock() to read_boot_clock64() and
read_persistent_clock() to read_persistent_clock64() using
timespec64 by converting clock_access_fn to use timespec64.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Thierry Reding <treding@nvidia.com> (for tegra part)
Cc: Russell King <rmk@dyn-67.arm.linux.org.uk>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-7-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/arm/include/asm/mach/time.h    |  3 +--
 arch/arm/kernel/time.c              |  6 +++---
 arch/arm/plat-omap/counter_32k.c    | 10 +---------
 drivers/clocksource/tegra20_timer.c | 10 +---------
 4 files changed, 6 insertions(+), 23 deletions(-)

diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index 90c12e1..0f79e4d 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -12,8 +12,7 @@
 
 extern void timer_tick(void);
 
-struct timespec;
-typedef void (*clock_access_fn)(struct timespec *);
+typedef void (*clock_access_fn)(struct timespec64 *);
 extern int register_persistent_clock(clock_access_fn read_boot,
 				     clock_access_fn read_persistent);
 
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 0cc7e58..a66e37e 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -76,7 +76,7 @@ void timer_tick(void)
 }
 #endif
 
-static void dummy_clock_access(struct timespec *ts)
+static void dummy_clock_access(struct timespec64 *ts)
 {
 	ts->tv_sec = 0;
 	ts->tv_nsec = 0;
@@ -85,12 +85,12 @@ static void dummy_clock_access(struct timespec *ts)
 static clock_access_fn __read_persistent_clock = dummy_clock_access;
 static clock_access_fn __read_boot_clock = dummy_clock_access;;
 
-void read_persistent_clock(struct timespec *ts)
+void read_persistent_clock64(struct timespec64 *ts)
 {
 	__read_persistent_clock(ts);
 }
 
-void read_boot_clock(struct timespec *ts)
+void read_boot_clock64(struct timespec64 *ts)
 {
 	__read_boot_clock(ts);
 }
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index b7b7b07..2438b96 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -70,14 +70,6 @@ static void omap_read_persistent_clock64(struct timespec64 *ts)
 	*ts = persistent_ts;
 }
 
-static void omap_read_persistent_clock(struct timespec *ts)
-{
-	struct timespec64 ts64;
-
-	omap_read_persistent_clock64(&ts64);
-	*ts = timespec64_to_timespec(ts64);
-}
-
 /**
  * omap_init_clocksource_32k - setup and register counter 32k as a
  * kernel clocksource
@@ -118,7 +110,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase)
 	}
 
 	sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
-	register_persistent_clock(NULL, omap_read_persistent_clock);
+	register_persistent_clock(NULL, omap_read_persistent_clock64);
 	pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
 
 	return 0;
diff --git a/drivers/clocksource/tegra20_timer.c b/drivers/clocksource/tegra20_timer.c
index 4a0a603..5a112d7 100644
--- a/drivers/clocksource/tegra20_timer.c
+++ b/drivers/clocksource/tegra20_timer.c
@@ -141,14 +141,6 @@ static void tegra_read_persistent_clock64(struct timespec64 *ts)
 	*ts = persistent_ts;
 }
 
-static void tegra_read_persistent_clock(struct timespec *ts)
-{
-	struct timespec ts64;
-
-	tegra_read_persistent_clock64(&ts64);
-	*ts = timespec64_to_timespec(ts64);
-}
-
 static unsigned long tegra_delay_timer_read_counter_long(void)
 {
 	return readl(timer_reg_base + TIMERUS_CNTR_1US);
@@ -259,7 +251,7 @@ static void __init tegra20_init_rtc(struct device_node *np)
 	else
 		clk_prepare_enable(clk);
 
-	register_persistent_clock(NULL, tegra_read_persistent_clock);
+	register_persistent_clock(NULL, tegra_read_persistent_clock64);
 }
 CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
 

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

* [tip:timers/core] drivers/rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement
  2015-04-02  3:34 ` [PATCH 07/21] rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement John Stultz
@ 2015-04-03  8:17   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: john.stultz, a.zummo, peterz, tglx, hpa, mingo, linux-kernel,
	pang.xunlei

Commit-ID:  8e4ff1a81aa91d12856287c7103d0301ac91351a
Gitweb:     http://git.kernel.org/tip/8e4ff1a81aa91d12856287c7103d0301ac91351a
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:27 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:24 +0200

drivers/rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement

Currently the rtc_class_op's set_mmss() function takes a 32-bit
second value (on 32-bit systems), which is problematic for dates
past y2038.

This patch provides a safe version named set_mmss64() using
y2038 safe time64_t.

After this patch, set_mmss() is deprecated and all its users
will be fixed to use set_mmss64(), it can be removed when having
no users.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
[jstultz: Add whitespace fix for checkpatch]
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-8-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/interface.c | 8 +++++++-
 drivers/rtc/systohc.c   | 5 ++++-
 include/linux/rtc.h     | 1 +
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 37215cf..d43ee40 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -72,7 +72,11 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
 		err = -ENODEV;
 	else if (rtc->ops->set_time)
 		err = rtc->ops->set_time(rtc->dev.parent, tm);
-	else if (rtc->ops->set_mmss) {
+	else if (rtc->ops->set_mmss64) {
+		time64_t secs64 = rtc_tm_to_time64(tm);
+
+		err = rtc->ops->set_mmss64(rtc->dev.parent, secs64);
+	} else if (rtc->ops->set_mmss) {
 		time64_t secs64 = rtc_tm_to_time64(tm);
 		err = rtc->ops->set_mmss(rtc->dev.parent, secs64);
 	} else
@@ -96,6 +100,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
 
 	if (!rtc->ops)
 		err = -ENODEV;
+	else if (rtc->ops->set_mmss64)
+		err = rtc->ops->set_mmss64(rtc->dev.parent, secs);
 	else if (rtc->ops->set_mmss)
 		err = rtc->ops->set_mmss(rtc->dev.parent, secs);
 	else if (rtc->ops->read_time && rtc->ops->set_time) {
diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c
index ef3c07a..7728d5e 100644
--- a/drivers/rtc/systohc.c
+++ b/drivers/rtc/systohc.c
@@ -35,7 +35,10 @@ int rtc_set_ntp_time(struct timespec64 now)
 	if (rtc) {
 		/* rtc_hctosys exclusively uses UTC, so we call set_time here,
 		 * not set_mmss. */
-		if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss))
+		if (rtc->ops &&
+		    (rtc->ops->set_time ||
+		     rtc->ops->set_mmss64 ||
+		     rtc->ops->set_mmss))
 			err = rtc_set_time(rtc, &tm);
 		rtc_class_close(rtc);
 	}
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index dcad7ee..8dcf682 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -77,6 +77,7 @@ struct rtc_class_ops {
 	int (*read_alarm)(struct device *, struct rtc_wkalrm *);
 	int (*set_alarm)(struct device *, struct rtc_wkalrm *);
 	int (*proc)(struct device *, struct seq_file *);
+	int (*set_mmss64)(struct device *, time64_t secs);
 	int (*set_mmss)(struct device *, unsigned long secs);
 	int (*read_callback)(struct device *, int data);
 	int (*alarm_irq_enable)(struct device *, unsigned int enabled);

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

* [tip:timers/core] drivers/rtc/test: Update driver to address y2038/y2106 issues
  2015-04-02  3:34 ` [PATCH 08/21] rtc/test: Update driver to address y2038/y2106 issues John Stultz
@ 2015-04-03  8:17   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: pang.xunlei, hpa, a.zummo, linux-kernel, mingo, john.stultz,
	peterz, tglx

Commit-ID:  4d644ab84c6ed66f7a628c74d83c34d85bec13bf
Gitweb:     http://git.kernel.org/tip/4d644ab84c6ed66f7a628c74d83c34d85bec13bf
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:28 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:24 +0200

drivers/rtc/test: Update driver to address y2038/y2106 issues

This driver has a number of y2038/y2106 issues.

This patch resolves them by:

 - Replacing get_seconds() with ktime_get_real_seconds()
 - Replacing rtc_time_to_tm() with rtc_time64_to_tm()

Also add test_rtc_set_mmss64() for testing rtc_class_ops's
set_mmss64(), which can be activated by "test_mmss64" module
parameter.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-9-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/rtc-test.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index 8f86fa9..3a2da4c 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -13,6 +13,10 @@
 #include <linux/rtc.h>
 #include <linux/platform_device.h>
 
+static int test_mmss64;
+module_param(test_mmss64, int, 0644);
+MODULE_PARM_DESC(test_mmss64, "Test struct rtc_class_ops.set_mmss64().");
+
 static struct platform_device *test0 = NULL, *test1 = NULL;
 
 static int test_rtc_read_alarm(struct device *dev,
@@ -30,7 +34,13 @@ static int test_rtc_set_alarm(struct device *dev,
 static int test_rtc_read_time(struct device *dev,
 	struct rtc_time *tm)
 {
-	rtc_time_to_tm(get_seconds(), tm);
+	rtc_time64_to_tm(ktime_get_real_seconds(), tm);
+	return 0;
+}
+
+static int test_rtc_set_mmss64(struct device *dev, time64_t secs)
+{
+	dev_info(dev, "%s, secs = %lld\n", __func__, (long long)secs);
 	return 0;
 }
 
@@ -55,7 +65,7 @@ static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
 	return 0;
 }
 
-static const struct rtc_class_ops test_rtc_ops = {
+static struct rtc_class_ops test_rtc_ops = {
 	.proc = test_rtc_proc,
 	.read_time = test_rtc_read_time,
 	.read_alarm = test_rtc_read_alarm,
@@ -101,6 +111,11 @@ static int test_probe(struct platform_device *plat_dev)
 	int err;
 	struct rtc_device *rtc;
 
+	if (test_mmss64) {
+		test_rtc_ops.set_mmss64 = test_rtc_set_mmss64;
+		test_rtc_ops.set_mmss = NULL;
+	}
+
 	rtc = devm_rtc_device_register(&plat_dev->dev, "test",
 				&test_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc)) {

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

* [tip:timers/core] drivers/rtc/ab3100: Update driver to address y2038/y2106 issues
  2015-04-02  3:34 ` [PATCH 09/21] rtc/ab3100: " John Stultz
@ 2015-04-03  8:17   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: john.stultz, tglx, peterz, linux-kernel, linus.walleij, a.zummo,
	pang.xunlei, hpa, mingo

Commit-ID:  5c7e11bc66647f2e4bc95de9b4302fff6d612f3a
Gitweb:     http://git.kernel.org/tip/5c7e11bc66647f2e4bc95de9b4302fff6d612f3a
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:29 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:25 +0200

drivers/rtc/ab3100: Update driver to address y2038/y2106 issues

This driver has a number of y2038/y2106 issues.

This patch resolves them by:

  - Replacing rtc_tm_to_time() with rtc_tm_to_time64()
  - Replacing rtc_time_to_tm() with rtc_time64_to_tm()
  - Changing ab3100_rtc_set_mmss() to use rtc_class_ops's set_mmss64()

After this patch, the driver should not have any remaining
y2038/y2106 issues.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-10-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/rtc-ab3100.c | 55 ++++++++++++++++++++++++------------------------
 1 file changed, 27 insertions(+), 28 deletions(-)

diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c
index 1d0340f..9b725c5 100644
--- a/drivers/rtc/rtc-ab3100.c
+++ b/drivers/rtc/rtc-ab3100.c
@@ -43,21 +43,21 @@
 /*
  * RTC clock functions and device struct declaration
  */
-static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int ab3100_rtc_set_mmss(struct device *dev, time64_t secs)
 {
 	u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2,
 		     AB3100_TI3, AB3100_TI4, AB3100_TI5};
 	unsigned char buf[6];
-	u64 fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2;
+	u64 hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2;
 	int err = 0;
 	int i;
 
-	buf[0] = (fat_time) & 0xFF;
-	buf[1] = (fat_time >> 8) & 0xFF;
-	buf[2] = (fat_time >> 16) & 0xFF;
-	buf[3] = (fat_time >> 24) & 0xFF;
-	buf[4] = (fat_time >> 32) & 0xFF;
-	buf[5] = (fat_time >> 40) & 0xFF;
+	buf[0] = (hw_counter) & 0xFF;
+	buf[1] = (hw_counter >> 8) & 0xFF;
+	buf[2] = (hw_counter >> 16) & 0xFF;
+	buf[3] = (hw_counter >> 24) & 0xFF;
+	buf[4] = (hw_counter >> 32) & 0xFF;
+	buf[5] = (hw_counter >> 40) & 0xFF;
 
 	for (i = 0; i < 6; i++) {
 		err = abx500_set_register_interruptible(dev, 0,
@@ -75,7 +75,7 @@ static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs)
 
 static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	unsigned long time;
+	time64_t time;
 	u8 rtcval;
 	int err;
 
@@ -88,7 +88,7 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 		dev_info(dev, "clock not set (lost power)");
 		return -EINVAL;
 	} else {
-		u64 fat_time;
+		u64 hw_counter;
 		u8 buf[6];
 
 		/* Read out time registers */
@@ -98,22 +98,21 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm)
 		if (err != 0)
 			return err;
 
-		fat_time = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
+		hw_counter = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) |
 			((u64) buf[3] << 24) | ((u64) buf[2] << 16) |
 			((u64) buf[1] << 8) | (u64) buf[0];
-		time = (unsigned long) (fat_time /
-					(u64) (AB3100_RTC_CLOCK_RATE * 2));
+		time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
 	}
 
-	rtc_time_to_tm(time, tm);
+	rtc_time64_to_tm(time, tm);
 
 	return rtc_valid_tm(tm);
 }
 
 static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
-	unsigned long time;
-	u64 fat_time;
+	time64_t time;
+	u64 hw_counter;
 	u8 buf[6];
 	u8 rtcval;
 	int err;
@@ -134,11 +133,11 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 						     AB3100_AL0, buf, 4);
 	if (err)
 		return err;
-	fat_time = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
+	hw_counter = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) |
 		((u64) buf[1] << 24) | ((u64) buf[0] << 16);
-	time = (unsigned long) (fat_time / (u64) (AB3100_RTC_CLOCK_RATE * 2));
+	time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2);
 
-	rtc_time_to_tm(time, &alarm->time);
+	rtc_time64_to_tm(time, &alarm->time);
 
 	return rtc_valid_tm(&alarm->time);
 }
@@ -147,17 +146,17 @@ static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3};
 	unsigned char buf[4];
-	unsigned long secs;
-	u64 fat_time;
+	time64_t secs;
+	u64 hw_counter;
 	int err;
 	int i;
 
-	rtc_tm_to_time(&alarm->time, &secs);
-	fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2;
-	buf[0] = (fat_time >> 16) & 0xFF;
-	buf[1] = (fat_time >> 24) & 0xFF;
-	buf[2] = (fat_time >> 32) & 0xFF;
-	buf[3] = (fat_time >> 40) & 0xFF;
+	secs = rtc_tm_to_time64(&alarm->time);
+	hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2;
+	buf[0] = (hw_counter >> 16) & 0xFF;
+	buf[1] = (hw_counter >> 24) & 0xFF;
+	buf[2] = (hw_counter >> 32) & 0xFF;
+	buf[3] = (hw_counter >> 40) & 0xFF;
 
 	/* Set the alarm */
 	for (i = 0; i < 4; i++) {
@@ -193,7 +192,7 @@ static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled)
 
 static const struct rtc_class_ops ab3100_rtc_ops = {
 	.read_time	= ab3100_rtc_read_time,
-	.set_mmss	= ab3100_rtc_set_mmss,
+	.set_mmss64	= ab3100_rtc_set_mmss,
 	.read_alarm	= ab3100_rtc_read_alarm,
 	.set_alarm	= ab3100_rtc_set_alarm,
 	.alarm_irq_enable = ab3100_rtc_irq_enable,

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

* [tip:timers/core] drivers/rtc/mc13xxx: Update driver to address y2038/y2106 issues
  2015-04-02  3:34 ` [PATCH 10/21] rtc/mc13xxx: " John Stultz
@ 2015-04-03  8:18   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: pang.xunlei, mingo, tglx, hpa, john.stultz, a.zummo, peterz,
	linux-kernel

Commit-ID:  0307b0d77a0830b0fd4a22b5db4a9fa723a5fa5f
Gitweb:     http://git.kernel.org/tip/0307b0d77a0830b0fd4a22b5db4a9fa723a5fa5f
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:30 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:26 +0200

drivers/rtc/mc13xxx: Update driver to address y2038/y2106 issues

This driver has a number of y2038/y2106 issues.

This patch resolves them by:

  - Replacing rtc_time_to_tm() with rtc_time64_to_tm()
  - Changing mc13xxx_rtc_set_mmss() to use rtc_class_ops's set_mmss64()

After this patch, the driver should not have any remaining
y2038/y2106 issues.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-11-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/rtc-mc13xxx.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c
index 5bce904..32df1d8 100644
--- a/drivers/rtc/rtc-mc13xxx.c
+++ b/drivers/rtc/rtc-mc13xxx.c
@@ -83,20 +83,19 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)
 			return ret;
 	} while (days1 != days2);
 
-	rtc_time_to_tm(days1 * SEC_PER_DAY + seconds, tm);
+	rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm);
 
 	return rtc_valid_tm(tm);
 }
 
-static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs)
+static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 	unsigned int seconds, days;
 	unsigned int alarmseconds;
 	int ret;
 
-	seconds = secs % SEC_PER_DAY;
-	days = secs / SEC_PER_DAY;
+	days = div_s64_rem(secs, SEC_PER_DAY, &seconds);
 
 	mc13xxx_lock(priv->mc13xxx);
 
@@ -159,7 +158,7 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
 	unsigned seconds, days;
-	unsigned long s1970;
+	time64_t s1970;
 	int enabled, pending;
 	int ret;
 
@@ -189,10 +188,10 @@ out:
 	alarm->enabled = enabled;
 	alarm->pending = pending;
 
-	s1970 = days * SEC_PER_DAY + seconds;
+	s1970 = (time64_t)days * SEC_PER_DAY + seconds;
 
-	rtc_time_to_tm(s1970, &alarm->time);
-	dev_dbg(dev, "%s: %lu\n", __func__, s1970);
+	rtc_time64_to_tm(s1970, &alarm->time);
+	dev_dbg(dev, "%s: %lld\n", __func__, (long long)s1970);
 
 	return 0;
 }
@@ -200,8 +199,8 @@ out:
 static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
 	struct mc13xxx_rtc *priv = dev_get_drvdata(dev);
-	unsigned long s1970;
-	unsigned seconds, days;
+	time64_t s1970;
+	u32 seconds, days;
 	int ret;
 
 	mc13xxx_lock(priv->mc13xxx);
@@ -215,20 +214,17 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 	if (unlikely(ret))
 		goto out;
 
-	ret = rtc_tm_to_time(&alarm->time, &s1970);
-	if (unlikely(ret))
-		goto out;
+	s1970 = rtc_tm_to_time64(&alarm->time);
 
-	dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff",
-			s1970);
+	dev_dbg(dev, "%s: o%2.s %lld\n", __func__, alarm->enabled ? "n" : "ff",
+			(long long)s1970);
 
 	ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled,
 			MC13XXX_IRQ_TODA);
 	if (unlikely(ret))
 		goto out;
 
-	seconds = s1970 % SEC_PER_DAY;
-	days = s1970 / SEC_PER_DAY;
+	days = div_s64_rem(s1970, SEC_PER_DAY, &seconds);
 
 	ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days);
 	if (unlikely(ret))
@@ -268,7 +264,7 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
 
 static const struct rtc_class_ops mc13xxx_rtc_ops = {
 	.read_time = mc13xxx_rtc_read_time,
-	.set_mmss = mc13xxx_rtc_set_mmss,
+	.set_mmss64 = mc13xxx_rtc_set_mmss,
 	.read_alarm = mc13xxx_rtc_read_alarm,
 	.set_alarm = mc13xxx_rtc_set_alarm,
 	.alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable,

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

* [tip:timers/core] drivers/rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time
  2015-04-02  3:34 ` [PATCH 11/21] rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time John Stultz
@ 2015-04-03  8:18   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: a.zummo, tglx, hpa, mingo, john.stultz, pang.xunlei,
	linux-kernel, peterz

Commit-ID:  482494a8d395877c4776a3d76f89342d7ad7c4c6
Gitweb:     http://git.kernel.org/tip/482494a8d395877c4776a3d76f89342d7ad7c4c6
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:31 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:27 +0200

drivers/rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time

rtc_class_ops's set_alarm() shouldn't deal with the alarm date,
as this is handled in the rtc core.

See rtc_dev_ioctl()'s RTC_ALM_SET and RTC_WKALM_SET cases.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-12-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/rtc-mxc.c | 22 ++++------------------
 1 file changed, 4 insertions(+), 18 deletions(-)

diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 3c3f8d1..a7b218f 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -173,29 +173,18 @@ static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time)
  * This function updates the RTC alarm registers and then clears all the
  * interrupt status bits.
  */
-static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
+static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
 {
-	struct rtc_time alarm_tm, now_tm;
-	unsigned long now, time;
+	unsigned long time;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	now = get_alarm_or_time(dev, MXC_RTC_TIME);
-	rtc_time_to_tm(now, &now_tm);
-	alarm_tm.tm_year = now_tm.tm_year;
-	alarm_tm.tm_mon = now_tm.tm_mon;
-	alarm_tm.tm_mday = now_tm.tm_mday;
-	alarm_tm.tm_hour = alrm->tm_hour;
-	alarm_tm.tm_min = alrm->tm_min;
-	alarm_tm.tm_sec = alrm->tm_sec;
-	rtc_tm_to_time(&alarm_tm, &time);
+	rtc_tm_to_time(alrm, &time);
 
 	/* clear all the interrupt status bits */
 	writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR);
 	set_alarm_or_time(dev, MXC_RTC_ALARM, time);
-
-	return 0;
 }
 
 static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit,
@@ -346,11 +335,8 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-	int ret;
 
-	ret = rtc_update_alarm(dev, &alrm->time);
-	if (ret)
-		return ret;
+	rtc_update_alarm(dev, &alrm->time);
 
 	memcpy(&pdata->g_rtc_alarm, &alrm->time, sizeof(struct rtc_time));
 	mxc_rtc_irq_enable(dev, RTC_ALM_BIT, alrm->enabled);

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

* [tip:timers/core] drivers/rtc/mxc: Convert get_alarm_or_time()/ set_alarm_or_time() to use time64_t
  2015-04-02  3:34 ` [PATCH 12/21] rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use time64_t John Stultz
@ 2015-04-03  8:18   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:18 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, linux-kernel, hpa, tglx, pang.xunlei, a.zummo, mingo,
	john.stultz

Commit-ID:  a015b8aabfd2fb58875dea001f1eac8100eacc2e
Gitweb:     http://git.kernel.org/tip/a015b8aabfd2fb58875dea001f1eac8100eacc2e
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:32 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:28 +0200

drivers/rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use time64_t

We want to convert mxc_rtc_set_mmss() to use rtc_class_ops's
set_mmss64(), but it uses get_alarm_or_time()/set_alarm_or_time()
internal interfaces which are y2038 unsafe.

So here as a separate patch, it converts these two internal
interfaces of "mxc" to use safe time64_t to make some
preparations.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-13-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/rtc-mxc.c | 29 ++++++++++++++---------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index a7b218f..83cba23 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -106,7 +106,7 @@ static inline int is_imx1_rtc(struct rtc_plat_data *data)
  * This function is used to obtain the RTC time or the alarm value in
  * second.
  */
-static u32 get_alarm_or_time(struct device *dev, int time_alarm)
+static time64_t get_alarm_or_time(struct device *dev, int time_alarm)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
@@ -129,29 +129,28 @@ static u32 get_alarm_or_time(struct device *dev, int time_alarm)
 	hr = hr_min >> 8;
 	min = hr_min & 0xff;
 
-	return (((day * 24 + hr) * 60) + min) * 60 + sec;
+	return ((((time64_t)day * 24 + hr) * 60) + min) * 60 + sec;
 }
 
 /*
  * This function sets the RTC alarm value or the time value.
  */
-static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time)
+static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time)
 {
-	u32 day, hr, min, sec, temp;
+	u32 tod, day, hr, min, sec, temp;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	day = time / 86400;
-	time -= day * 86400;
+	day = div_s64_rem(time, 86400, &tod);
 
 	/* time is within a day now */
-	hr = time / 3600;
-	time -= hr * 3600;
+	hr = tod / 3600;
+	tod -= hr * 3600;
 
 	/* time is within an hour now */
-	min = time / 60;
-	sec = time - min * 60;
+	min = tod / 60;
+	sec = tod - min * 60;
 
 	temp = (hr << 8) + min;
 
@@ -175,12 +174,12 @@ static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time)
  */
 static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm)
 {
-	unsigned long time;
+	time64_t time;
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	rtc_tm_to_time(alrm, &time);
+	time = rtc_tm_to_time64(alrm);
 
 	/* clear all the interrupt status bits */
 	writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR);
@@ -272,14 +271,14 @@ static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
  */
 static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
-	u32 val;
+	time64_t val;
 
 	/* Avoid roll-over from reading the different registers */
 	do {
 		val = get_alarm_or_time(dev, MXC_RTC_TIME);
 	} while (val != get_alarm_or_time(dev, MXC_RTC_TIME));
 
-	rtc_time_to_tm(val, tm);
+	rtc_time64_to_tm(val, tm);
 
 	return 0;
 }
@@ -322,7 +321,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
 	void __iomem *ioaddr = pdata->ioaddr;
 
-	rtc_time_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time);
+	rtc_time64_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time);
 	alrm->pending = ((readw(ioaddr + RTC_RTCISR) & RTC_ALM_BIT)) ? 1 : 0;
 
 	return 0;

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

* [tip:timers/core] drivers/rtc/mxc: Update driver to address y2038 /y2106 issues
  2015-04-02  3:34 ` [PATCH 13/21] rtc/mxc: Update driver to address y2038/y2106 issues John Stultz
@ 2015-04-03  8:19   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, tglx, linux-kernel, pang.xunlei, mingo, john.stultz,
	a.zummo, hpa

Commit-ID:  933623c38f014b10db564f0ec44f9db64a5ced84
Gitweb:     http://git.kernel.org/tip/933623c38f014b10db564f0ec44f9db64a5ced84
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:33 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:29 +0200

drivers/rtc/mxc: Update driver to address y2038/y2106 issues

This driver has a number of y2038/y2106 issues.

This patch resolves them by:

  - Replacing rtc_time_to_tm() with rtc_time64_to_tm()
  - Replacing rtc_tm_to_time() with rtc_tm_to_time64()
  - Changing mxc_rtc_set_mmss() to use rtc_class_ops's set_mmss64()

After this patch, the driver should not have any remaining
y2038/y2106 issues.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-14-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/rtc-mxc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index 83cba23..09d422b 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -286,7 +286,7 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
 /*
  * This function sets the internal RTC time based on tm in Gregorian date.
  */
-static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
+static int mxc_rtc_set_mmss(struct device *dev, time64_t time)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
@@ -297,9 +297,9 @@ static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
 	if (is_imx1_rtc(pdata)) {
 		struct rtc_time tm;
 
-		rtc_time_to_tm(time, &tm);
+		rtc_time64_to_tm(time, &tm);
 		tm.tm_year = 70;
-		rtc_tm_to_time(&tm, &time);
+		time = rtc_tm_to_time64(&tm);
 	}
 
 	/* Avoid roll-over from reading the different registers */
@@ -347,7 +347,7 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static struct rtc_class_ops mxc_rtc_ops = {
 	.release		= mxc_rtc_release,
 	.read_time		= mxc_rtc_read_time,
-	.set_mmss		= mxc_rtc_set_mmss,
+	.set_mmss64		= mxc_rtc_set_mmss,
 	.read_alarm		= mxc_rtc_read_alarm,
 	.set_alarm		= mxc_rtc_set_alarm,
 	.alarm_irq_enable	= mxc_rtc_alarm_irq_enable,

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

* [tip:timers/core] alpha, rtc: Change to use rtc_class_ops' s set_mmss64()
  2015-04-02  3:34 ` [PATCH 14/21] alpha: rtc: Change to use rtc_class_ops's set_mmss64() John Stultz
@ 2015-04-03  8:19   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, tglx, mingo, a.zummo, rth, pang.xunlei, hpa,
	linux-kernel, john.stultz

Commit-ID:  a5312f56e0a67deed5c7d1191140e00b6d367e01
Gitweb:     http://git.kernel.org/tip/a5312f56e0a67deed5c7d1191140e00b6d367e01
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:34 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:30 +0200

alpha, rtc: Change to use rtc_class_ops's set_mmss64()

Change alpha_rtc_set_mmss() and remote_set_mmss() to use
rtc_class_ops's set_mmss64(), to be y2038 safe.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Richard Henderson <rth@twiddle.net>
Link: http://lkml.kernel.org/r/1427945681-29972-15-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/alpha/kernel/rtc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/alpha/kernel/rtc.c b/arch/alpha/kernel/rtc.c
index c8d284d..f535a3f 100644
--- a/arch/alpha/kernel/rtc.c
+++ b/arch/alpha/kernel/rtc.c
@@ -116,7 +116,7 @@ alpha_rtc_set_time(struct device *dev, struct rtc_time *tm)
 }
 
 static int
-alpha_rtc_set_mmss(struct device *dev, unsigned long nowtime)
+alpha_rtc_set_mmss(struct device *dev, time64_t nowtime)
 {
 	int retval = 0;
 	int real_seconds, real_minutes, cmos_minutes;
@@ -211,7 +211,7 @@ alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 static const struct rtc_class_ops alpha_rtc_ops = {
 	.read_time = alpha_rtc_read_time,
 	.set_time = alpha_rtc_set_time,
-	.set_mmss = alpha_rtc_set_mmss,
+	.set_mmss64 = alpha_rtc_set_mmss,
 	.ioctl = alpha_rtc_ioctl,
 };
 
@@ -276,7 +276,7 @@ do_remote_mmss(void *data)
 }
 
 static int
-remote_set_mmss(struct device *dev, unsigned long now)
+remote_set_mmss(struct device *dev, time64_t now)
 {
 	union remote_data x;
 	if (smp_processor_id() != boot_cpuid) {
@@ -290,7 +290,7 @@ remote_set_mmss(struct device *dev, unsigned long now)
 static const struct rtc_class_ops remote_rtc_ops = {
 	.read_time = remote_read_time,
 	.set_time = remote_set_time,
-	.set_mmss = remote_set_mmss,
+	.set_mmss64 = remote_set_mmss,
 	.ioctl = alpha_rtc_ioctl,
 };
 #endif

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

* [tip:timers/core] time: Don' t build timekeeping_inject_sleeptime64() if no one uses it
  2015-04-02  3:34 ` [PATCH 15/21] time: Don't build timekeeping_inject_sleeptime64() if no one uses it John Stultz
@ 2015-04-03  8:19   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, peterz, linux-kernel, tglx, pang.xunlei, hpa, john.stultz

Commit-ID:  7f2981393af31a854879f2496cab4c978e886902
Gitweb:     http://git.kernel.org/tip/7f2981393af31a854879f2496cab4c978e886902
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:35 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:31 +0200

time: Don't build timekeeping_inject_sleeptime64() if no one uses it

timekeeping_inject_sleeptime64() is only used by RTC
suspend/resume, so add build dependencies on the necessary RTC
related macros.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
[ Improve commit message clarity. ]
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-16-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/time/timekeeping.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b1dbfa5..3be559b 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1280,6 +1280,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
 	tk_debug_account_sleep_time(delta);
 }
 
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
 /**
  * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
  * @delta: pointer to a timespec64 delta value
@@ -1317,6 +1318,7 @@ void timekeeping_inject_sleeptime64(struct timespec64 *delta)
 	/* signal hrtimers about time change */
 	clock_was_set();
 }
+#endif
 
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.

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

* [tip:timers/core] drivers/rtc: Remove redundant rtc_valid_tm() from rtc_resume()
  2015-04-02  3:34 ` [PATCH 16/21] rtc: Remove redundant rtc_valid_tm() from rtc_resume() John Stultz
@ 2015-04-03  8:19   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:19 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: john.stultz, peterz, linux-kernel, mingo, hpa, tglx, pang.xunlei

Commit-ID:  814dcf8ead04f5ebcec74af06c705b207887f0fa
Gitweb:     http://git.kernel.org/tip/814dcf8ead04f5ebcec74af06c705b207887f0fa
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:36 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:32 +0200

drivers/rtc: Remove redundant rtc_valid_tm() from rtc_resume()

rtc_read_time() has already judged valid tm by rtc_valid_tm(),
so just remove it.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-17-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/class.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 472a5ad..d40760a 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -117,10 +117,6 @@ static int rtc_resume(struct device *dev)
 		return 0;
 	}
 
-	if (rtc_valid_tm(&tm) != 0) {
-		pr_debug("%s:  bogus resume time\n", dev_name(&rtc->dev));
-		return 0;
-	}
 	new_rtc.tv_sec = rtc_tm_to_time64(&tm);
 	new_rtc.tv_nsec = 0;
 

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

* [tip:timers/core] time: Fix a bug in timekeeping_suspend() with no persistent clock
  2015-04-02  3:34 ` [PATCH 17/21] time: Fix a bug in timekeeping_suspend() with no persistent clock John Stultz
  2015-04-03  6:16   ` Ingo Molnar
@ 2015-04-03  8:20   ` tip-bot for Xunlei Pang
  1 sibling, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, john.stultz, pang.xunlei, tglx, linux-kernel, hpa, peterz

Commit-ID:  264bb3f79f2a465477cdcd2f0554e21aedc443a3
Gitweb:     http://git.kernel.org/tip/264bb3f79f2a465477cdcd2f0554e21aedc443a3
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:37 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:33 +0200

time: Fix a bug in timekeeping_suspend() with no persistent clock

When there's no persistent clock, normally
timekeeping_suspend_time should always be zero, but this can
break in timekeeping_suspend().

At T1, there was a system suspend, so old_delta was assigned T1.
After some time, one time adjustment happened, and xtime got the
value of T1-dt(0s<dt<2s). Then, there comes another system
suspend soon after this adjustment, obviously we will get a
small negative delta_delta, resulting in a negative
timekeeping_suspend_time.

This is problematic, when doing timekeeping_resume() if there is
no nonstop clocksource for example, it will hit the else leg and
inject the improper sleeptime which is the wrong logic.

So, we can solve this problem by only doing delta related code
when the persistent clock is existent. Actually the code only
makes sense for persistent clock cases.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-18-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/time/timekeeping.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 3be559b..b7db491 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1255,7 +1255,7 @@ void __init timekeeping_init(void)
 	raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
 }
 
-/* time in seconds when suspend began */
+/* time in seconds when suspend began for persistent clock */
 static struct timespec64 timekeeping_suspend_time;
 
 /**
@@ -1428,24 +1428,26 @@ int timekeeping_suspend(void)
 	timekeeping_forward_now(tk);
 	timekeeping_suspended = 1;
 
-	/*
-	 * To avoid drift caused by repeated suspend/resumes,
-	 * which each can add ~1 second drift error,
-	 * try to compensate so the difference in system time
-	 * and persistent_clock time stays close to constant.
-	 */
-	delta = timespec64_sub(tk_xtime(tk), timekeeping_suspend_time);
-	delta_delta = timespec64_sub(delta, old_delta);
-	if (abs(delta_delta.tv_sec)  >= 2) {
+	if (has_persistent_clock()) {
 		/*
-		 * if delta_delta is too large, assume time correction
-		 * has occured and set old_delta to the current delta.
+		 * To avoid drift caused by repeated suspend/resumes,
+		 * which each can add ~1 second drift error,
+		 * try to compensate so the difference in system time
+		 * and persistent_clock time stays close to constant.
 		 */
-		old_delta = delta;
-	} else {
-		/* Otherwise try to adjust old_system to compensate */
-		timekeeping_suspend_time =
-			timespec64_add(timekeeping_suspend_time, delta_delta);
+		delta = timespec64_sub(tk_xtime(tk), timekeeping_suspend_time);
+		delta_delta = timespec64_sub(delta, old_delta);
+		if (abs(delta_delta.tv_sec) >= 2) {
+			/*
+			 * if delta_delta is too large, assume time correction
+			 * has occurred and set old_delta to the current delta.
+			 */
+			old_delta = delta;
+		} else {
+			/* Otherwise try to adjust old_system to compensate */
+			timekeeping_suspend_time =
+				timespec64_add(timekeeping_suspend_time, delta_delta);
+		}
 	}
 
 	timekeeping_update(tk, TK_MIRROR);

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

* [tip:timers/core] time, drivers/rtc: Don't bother with rtc_resume () for the nonstop clocksource
  2015-04-02  3:34 ` [PATCH 18/21] time: rtc: Don't bother into rtc_resume() for the nonstop clocksource John Stultz
@ 2015-04-03  8:20   ` tip-bot for Xunlei Pang
  0 siblings, 0 replies; 55+ messages in thread
From: tip-bot for Xunlei Pang @ 2015-04-03  8:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, pang.xunlei, linux-kernel, john.stultz, tglx, mingo, hpa

Commit-ID:  0fa88cb4b82b5cf7429bc1cef9db006ca035754e
Gitweb:     http://git.kernel.org/tip/0fa88cb4b82b5cf7429bc1cef9db006ca035754e
Author:     Xunlei Pang <pang.xunlei@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:38 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:34 +0200

time, drivers/rtc: Don't bother with rtc_resume() for the nonstop clocksource

If a system does not provide a persistent_clock(), the time
will be updated on resume by rtc_resume(). With the addition
of the non-stop clocksources for suspend timing, those systems
set the time on resume in timekeeping_resume(), but may not
provide a valid persistent_clock().

This results in the rtc_resume() logic thinking no one has set
the time and it then will over-write the suspend time again,
which is not necessary and only increases clock error.

So, fix this for rtc_resume().

This patch also improves the name of persistent_clock_exist to
make it more grammatical.

Signed-off-by: Xunlei Pang <pang.xunlei@linaro.org>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-19-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/rtc/class.c         |  4 +--
 include/linux/timekeeping.h |  9 +++----
 kernel/time/timekeeping.c   | 66 +++++++++++++++++++++++++++++++++------------
 3 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index d40760a..c29ba7e 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -55,7 +55,7 @@ static int rtc_suspend(struct device *dev)
 	struct timespec64	delta, delta_delta;
 	int err;
 
-	if (has_persistent_clock())
+	if (timekeeping_rtc_skipsuspend())
 		return 0;
 
 	if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
@@ -102,7 +102,7 @@ static int rtc_resume(struct device *dev)
 	struct timespec64	sleep_time;
 	int err;
 
-	if (has_persistent_clock())
+	if (timekeeping_rtc_skipresume())
 		return 0;
 
 	rtc_hctosys_ret = -ENODEV;
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 7a2369d..99176af 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -248,6 +248,9 @@ static inline void timekeeping_clocktai(struct timespec *ts)
 /*
  * RTC specific
  */
+extern bool timekeeping_rtc_skipsuspend(void);
+extern bool timekeeping_rtc_skipresume(void);
+
 extern void timekeeping_inject_sleeptime64(struct timespec64 *delta);
 
 /*
@@ -259,14 +262,8 @@ extern void getnstime_raw_and_real(struct timespec *ts_raw,
 /*
  * Persistent clock related interfaces
  */
-extern bool persistent_clock_exist;
 extern int persistent_clock_is_local;
 
-static inline bool has_persistent_clock(void)
-{
-	return persistent_clock_exist;
-}
-
 extern void read_persistent_clock(struct timespec *ts);
 extern void read_persistent_clock64(struct timespec64 *ts);
 extern void read_boot_clock(struct timespec *ts);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b7db491..79b9bc6 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -64,9 +64,6 @@ static struct tk_fast tk_fast_raw  ____cacheline_aligned;
 /* flag for if timekeeping is suspended */
 int __read_mostly timekeeping_suspended;
 
-/* Flag for if there is a persistent clock on this platform */
-bool __read_mostly persistent_clock_exist = false;
-
 static inline void tk_normalize_xtime(struct timekeeper *tk)
 {
 	while (tk->tkr_mono.xtime_nsec >= ((u64)NSEC_PER_SEC << tk->tkr_mono.shift)) {
@@ -1204,6 +1201,12 @@ void __weak read_boot_clock64(struct timespec64 *ts64)
 	*ts64 = timespec_to_timespec64(ts);
 }
 
+/* Flag for if timekeeping_resume() has injected sleeptime */
+static bool sleeptime_injected;
+
+/* Flag for if there is a persistent clock on this platform */
+static bool persistent_clock_exists;
+
 /*
  * timekeeping_init - Initializes the clocksource and common timekeeping values
  */
@@ -1221,7 +1224,7 @@ void __init timekeeping_init(void)
 		now.tv_sec = 0;
 		now.tv_nsec = 0;
 	} else if (now.tv_sec || now.tv_nsec)
-		persistent_clock_exist = true;
+		persistent_clock_exists = true;
 
 	read_boot_clock64(&boot);
 	if (!timespec64_valid_strict(&boot)) {
@@ -1282,11 +1285,47 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
 
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
 /**
+ * We have three kinds of time sources to use for sleep time
+ * injection, the preference order is:
+ * 1) non-stop clocksource
+ * 2) persistent clock (ie: RTC accessible when irqs are off)
+ * 3) RTC
+ *
+ * 1) and 2) are used by timekeeping, 3) by RTC subsystem.
+ * If system has neither 1) nor 2), 3) will be used finally.
+ *
+ *
+ * If timekeeping has injected sleeptime via either 1) or 2),
+ * 3) becomes needless, so in this case we don't need to call
+ * rtc_resume(), and this is what timekeeping_rtc_skipresume()
+ * means.
+ */
+bool timekeeping_rtc_skipresume(void)
+{
+	return sleeptime_injected;
+}
+
+/**
+ * 1) can be determined whether to use or not only when doing
+ * timekeeping_resume() which is invoked after rtc_suspend(),
+ * so we can't skip rtc_suspend() surely if system has 1).
+ *
+ * But if system has 2), 2) will definitely be used, so in this
+ * case we don't need to call rtc_suspend(), and this is what
+ * timekeeping_rtc_skipsuspend() means.
+ */
+bool timekeeping_rtc_skipsuspend(void)
+{
+	return persistent_clock_exists;
+}
+
+/**
  * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
  * @delta: pointer to a timespec64 delta value
  *
  * This hook is for architectures that cannot support read_persistent_clock64
  * because their RTC/persistent clock is only accessible when irqs are enabled.
+ * and also don't have an effective nonstop clocksource.
  *
  * This function should only be called by rtc_resume(), and allows
  * a suspend offset to be injected into the timekeeping values.
@@ -1296,13 +1335,6 @@ void timekeeping_inject_sleeptime64(struct timespec64 *delta)
 	struct timekeeper *tk = &tk_core.timekeeper;
 	unsigned long flags;
 
-	/*
-	 * Make sure we don't set the clock twice, as timekeeping_resume()
-	 * already did it
-	 */
-	if (has_persistent_clock())
-		return;
-
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
 
@@ -1334,8 +1366,8 @@ void timekeeping_resume(void)
 	unsigned long flags;
 	struct timespec64 ts_new, ts_delta;
 	cycle_t cycle_now, cycle_delta;
-	bool suspendtime_found = false;
 
+	sleeptime_injected = false;
 	read_persistent_clock64(&ts_new);
 
 	clockevents_resume();
@@ -1381,13 +1413,13 @@ void timekeeping_resume(void)
 		nsec += ((u64) cycle_delta * mult) >> shift;
 
 		ts_delta = ns_to_timespec64(nsec);
-		suspendtime_found = true;
+		sleeptime_injected = true;
 	} else if (timespec64_compare(&ts_new, &timekeeping_suspend_time) > 0) {
 		ts_delta = timespec64_sub(ts_new, timekeeping_suspend_time);
-		suspendtime_found = true;
+		sleeptime_injected = true;
 	}
 
-	if (suspendtime_found)
+	if (sleeptime_injected)
 		__timekeeping_inject_sleeptime(tk, &ts_delta);
 
 	/* Re-base the last cycle value */
@@ -1421,14 +1453,14 @@ int timekeeping_suspend(void)
 	 * value returned, update the persistent_clock_exists flag.
 	 */
 	if (timekeeping_suspend_time.tv_sec || timekeeping_suspend_time.tv_nsec)
-		persistent_clock_exist = true;
+		persistent_clock_exists = true;
 
 	raw_spin_lock_irqsave(&timekeeper_lock, flags);
 	write_seqcount_begin(&tk_core.seq);
 	timekeeping_forward_now(tk);
 	timekeeping_suspended = 1;
 
-	if (has_persistent_clock()) {
+	if (persistent_clock_exists) {
 		/*
 		 * To avoid drift caused by repeated suspend/resumes,
 		 * which each can add ~1 second drift error,

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

* [tip:timers/core] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
  2015-04-02  3:34 ` [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin John Stultz
  2015-04-02  8:50   ` Peter Zijlstra
@ 2015-04-03  8:20   ` tip-bot for John Stultz
  1 sibling, 0 replies; 55+ messages in thread
From: tip-bot for John Stultz @ 2015-04-03  8:20 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, tglx, hpa, richardcochran, mingo, john.stultz,
	peterz, prarit

Commit-ID:  8e56f33f8439b2f8e7f4ae7f3d0bfe683ecc3b09
Gitweb:     http://git.kernel.org/tip/8e56f33f8439b2f8e7f4ae7f3d0bfe683ecc3b09
Author:     John Stultz <john.stultz@linaro.org>
AuthorDate: Wed, 1 Apr 2015 20:34:39 -0700
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 3 Apr 2015 08:18:35 +0200

clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin

Ingo noted that the description of clocks_calc_max_nsecs()'s
50% safety margin was somewhat circular. So this patch tries
to improve the comment to better explain what we mean by the
50% safety margin and why we need it.

Signed-off-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1427945681-29972-20-git-send-email-john.stultz@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 kernel/time/clocksource.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index c3be3c7..15facb1 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -472,8 +472,11 @@ static u32 clocksource_max_adjustment(struct clocksource *cs)
  * @max_cyc:	maximum cycle value before potential overflow (does not include
  *		any safety margin)
  *
- * NOTE: This function includes a safety margin of 50%, so that bad clock values
- * can be detected.
+ * NOTE: This function includes a safety margin of 50%, in other words, we
+ * return half the number of nanoseconds the hardware counter can technically
+ * cover. This is done so that we can potentially detect problems caused by
+ * delayed timers or bad hardware, which might result in time intervals that
+ * are larger then what the math used can handle without overflows.
  */
 u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cyc)
 {

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

end of thread, other threads:[~2015-04-03  8:32 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-02  3:34 [PATCH 00/21] 4.1 time and rtc changes for tip/timers/core John Stultz
2015-04-02  3:34 ` [PATCH 01/21] time: Add y2038 safe read_boot_clock64() John Stultz
2015-04-03  8:15   ` [tip:timers/core] " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 02/21] time: Add y2038 safe read_persistent_clock64() John Stultz
2015-04-03  8:15   ` [tip:timers/core] " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 03/21] time: Add y2038 safe update_persistent_clock64() John Stultz
2015-04-03  8:16   ` [tip:timers/core] time: Add y2038 safe update_persistent_clock64( ) tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 04/21] ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement John Stultz
2015-04-03  8:16   ` [tip:timers/core] " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 05/21] ARM: tegra: clock: Provide y2038-safe tegra_read_persistent_clock() replacement John Stultz
2015-04-03  8:16   ` [tip:timers/core] clocksource/drivers/tegra: " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 06/21] ARM: time: Provide read_boot_clock64() and read_persistent_clock64() John Stultz
2015-04-03  8:17   ` [tip:timers/core] ARM, clocksource/drivers: Provide read_boot_clock64() and read_persistent_clock64() and use them tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 07/21] rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement John Stultz
2015-04-03  8:17   ` [tip:timers/core] drivers/rtc: " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 08/21] rtc/test: Update driver to address y2038/y2106 issues John Stultz
2015-04-03  8:17   ` [tip:timers/core] drivers/rtc/test: " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 09/21] rtc/ab3100: " John Stultz
2015-04-03  8:17   ` [tip:timers/core] drivers/rtc/ab3100: " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 10/21] rtc/mc13xxx: " John Stultz
2015-04-03  8:18   ` [tip:timers/core] drivers/rtc/mc13xxx: " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 11/21] rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time John Stultz
2015-04-03  8:18   ` [tip:timers/core] drivers/rtc/mxc: " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 12/21] rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use time64_t John Stultz
2015-04-03  8:18   ` [tip:timers/core] drivers/rtc/mxc: Convert get_alarm_or_time()/ set_alarm_or_time() " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 13/21] rtc/mxc: Update driver to address y2038/y2106 issues John Stultz
2015-04-03  8:19   ` [tip:timers/core] drivers/rtc/mxc: Update driver to address y2038 /y2106 issues tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 14/21] alpha: rtc: Change to use rtc_class_ops's set_mmss64() John Stultz
2015-04-03  8:19   ` [tip:timers/core] alpha, rtc: Change to use rtc_class_ops' s set_mmss64() tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 15/21] time: Don't build timekeeping_inject_sleeptime64() if no one uses it John Stultz
2015-04-03  8:19   ` [tip:timers/core] time: Don' t " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 16/21] rtc: Remove redundant rtc_valid_tm() from rtc_resume() John Stultz
2015-04-03  8:19   ` [tip:timers/core] drivers/rtc: " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 17/21] time: Fix a bug in timekeeping_suspend() with no persistent clock John Stultz
2015-04-03  6:16   ` Ingo Molnar
2015-04-03  8:20   ` [tip:timers/core] " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 18/21] time: rtc: Don't bother into rtc_resume() for the nonstop clocksource John Stultz
2015-04-03  8:20   ` [tip:timers/core] time, drivers/rtc: Don't bother with rtc_resume () " tip-bot for Xunlei Pang
2015-04-02  3:34 ` [PATCH 19/21] clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin John Stultz
2015-04-02  8:50   ` Peter Zijlstra
2015-04-02 17:30     ` John Stultz
2015-04-02 18:34       ` Peter Zijlstra
2015-04-02 18:41         ` John Stultz
2015-04-02 18:43           ` Peter Zijlstra
2015-04-02 18:50             ` John Stultz
2015-04-02 19:04               ` Peter Zijlstra
2015-04-03  8:20   ` [tip:timers/core] " tip-bot for John Stultz
2015-04-02  3:34 ` [PATCH 20/21] timekeeping: Change timekeeping_check_update() to take a tk_read_base John Stultz
2015-04-02  3:34 ` [PATCH 21/21] time: Rework debugging variables so they aren't global John Stultz
2015-04-02  7:47   ` Peter Zijlstra
2015-04-02  7:51     ` Ingo Molnar
2015-04-02  8:36       ` Peter Zijlstra
2015-04-02  8:41         ` Peter Zijlstra
2015-04-02 17:32       ` John Stultz
2015-04-03  6:21         ` Ingo Molnar

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).