linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL][PATCH 0/4] Timekeeping items for 4.13
@ 2017-06-21  5:21 John Stultz
  2017-06-21  5:21 ` [PATCH 1/4] time: Clean up CLOCK_MONOTONIC_RAW time handling John Stultz
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: John Stultz @ 2017-06-21  5:21 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, Shuah Khan

Just a small set of changes, the biggest changes being the
MONOTONIC_RAW handling cleanup, and a new kselftest from
Miroslav. Also a a clear warning deprecating
CONFIG_GENERIC_TIME_VSYSCALL_OLD, which affects ppc and ia64.

Let me know if you have any thoughts or objections!

thanks
-john

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Shuah Khan <shuah@kernel.org>

The following changes since commit 8e6cec1c7c5afa489687c90be15d6ed82c742975:

  Merge branch 'clockevents/4.12-fixes' of https://git.linaro.org/people/daniel.lezcano/linux into timers/urgent (2017-06-20 12:50:32 +0200)

are available in the git repository at:

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

for you to fetch changes up to 767392565a3e618950fe1a5ff1ba11295f6332f4:

  kselftests: timers: Add test for frequency step (2017-06-20 22:14:45 -0700)

----------------------------------------------------------------
John Stultz (2):
  time: Clean up CLOCK_MONOTONIC_RAW time handling
  time: Add warning about imminent deprecation of
    CONFIG_GENERIC_TIME_VSYSCALL_OLD

Miroslav Lichvar (2):
  kselftests: timers: Fix inconsistency-check to not ignore first
    timestamp
  kselftests: timers: Add test for frequency step

 arch/arm64/kernel/vdso.c                           |   6 +-
 include/linux/timekeeper_internal.h                |   4 +-
 kernel/time/timekeeping.c                          |  46 ++--
 tools/testing/selftests/timers/Makefile            |   5 +-
 tools/testing/selftests/timers/freq-step.c         | 268 +++++++++++++++++++++
 .../testing/selftests/timers/inconsistency-check.c |   4 +-
 6 files changed, 303 insertions(+), 30 deletions(-)
 create mode 100644 tools/testing/selftests/timers/freq-step.c

-- 
2.7.4

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

* [PATCH 1/4] time: Clean up CLOCK_MONOTONIC_RAW time handling
  2017-06-21  5:21 [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
@ 2017-06-21  5:21 ` John Stultz
  2017-06-21  9:36   ` Will Deacon
  2017-06-21  5:21 ` [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD John Stultz
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: John Stultz @ 2017-06-21  5:21 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, Kevin Brodsky,
	Will Deacon, Daniel Mentz

Now that we fixed the sub-ns handling for CLOCK_MONOTONIC_RAW,
remove the duplicitive tk->raw_time.tv_nsec, which can be
stored in tk->tkr_raw.xtime_nsec (similarly to how its handled
for monotonic time).

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Daniel Mentz <danielmentz@google.com>
Tested-by: Daniel Mentz <danielmentz@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm64/kernel/vdso.c            |  6 ++---
 include/linux/timekeeper_internal.h |  4 ++--
 kernel/time/timekeeping.c           | 45 ++++++++++++++++++++-----------------
 3 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index d0cb007..7492d90 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -220,10 +220,8 @@ void update_vsyscall(struct timekeeper *tk)
 	if (!use_syscall) {
 		/* tkr_mono.cycle_last == tkr_raw.cycle_last */
 		vdso_data->cs_cycle_last	= tk->tkr_mono.cycle_last;
-		vdso_data->raw_time_sec		= tk->raw_time.tv_sec;
-		vdso_data->raw_time_nsec	= (tk->raw_time.tv_nsec <<
-						   tk->tkr_raw.shift) +
-						  tk->tkr_raw.xtime_nsec;
+		vdso_data->raw_time_sec         = tk->raw_sec;
+		vdso_data->raw_time_nsec        = tk->tkr_raw.xtime_nsec;
 		vdso_data->xtime_clock_sec	= tk->xtime_sec;
 		vdso_data->xtime_clock_nsec	= tk->tkr_mono.xtime_nsec;
 		vdso_data->cs_mono_mult		= tk->tkr_mono.mult;
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index f7043cc..0a0a53d 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -51,7 +51,7 @@ struct tk_read_base {
  * @clock_was_set_seq:	The sequence number of clock was set events
  * @cs_was_changed_seq:	The sequence number of clocksource change events
  * @next_leap_ktime:	CLOCK_MONOTONIC time value of a pending leap-second
- * @raw_time:		Monotonic raw base time in timespec64 format
+ * @raw_sec:		CLOCK_MONOTONIC_RAW  time in seconds
  * @cycle_interval:	Number of clock cycles in one NTP interval
  * @xtime_interval:	Number of clock shifted nano seconds in one NTP
  *			interval.
@@ -93,7 +93,7 @@ struct timekeeper {
 	unsigned int		clock_was_set_seq;
 	u8			cs_was_changed_seq;
 	ktime_t			next_leap_ktime;
-	struct timespec64	raw_time;
+	u64			raw_sec;
 
 	/* The following members are for timekeeping internal use */
 	u64			cycle_interval;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b602c48..0454bfa 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -72,6 +72,10 @@ static inline void tk_normalize_xtime(struct timekeeper *tk)
 		tk->tkr_mono.xtime_nsec -= (u64)NSEC_PER_SEC << tk->tkr_mono.shift;
 		tk->xtime_sec++;
 	}
+	while (tk->tkr_raw.xtime_nsec >= ((u64)NSEC_PER_SEC << tk->tkr_raw.shift)) {
+		tk->tkr_raw.xtime_nsec -= (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
+		tk->raw_sec++;
+	}
 }
 
 static inline struct timespec64 tk_xtime(struct timekeeper *tk)
@@ -285,12 +289,14 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
 	 /* if changing clocks, convert xtime_nsec shift units */
 	if (old_clock) {
 		int shift_change = clock->shift - old_clock->shift;
-		if (shift_change < 0)
+		if (shift_change < 0) {
 			tk->tkr_mono.xtime_nsec >>= -shift_change;
-		else
+			tk->tkr_raw.xtime_nsec >>= -shift_change;
+		} else {
 			tk->tkr_mono.xtime_nsec <<= shift_change;
+			tk->tkr_raw.xtime_nsec <<= shift_change;
+		}
 	}
-	tk->tkr_raw.xtime_nsec = 0;
 
 	tk->tkr_mono.shift = clock->shift;
 	tk->tkr_raw.shift = clock->shift;
@@ -619,9 +625,6 @@ static inline void tk_update_ktime_data(struct timekeeper *tk)
 	nsec = (u32) tk->wall_to_monotonic.tv_nsec;
 	tk->tkr_mono.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);
 
-	/* Update the monotonic raw base */
-	tk->tkr_raw.base = timespec64_to_ktime(tk->raw_time);
-
 	/*
 	 * The sum of the nanoseconds portions of xtime and
 	 * wall_to_monotonic can be greater/equal one second. Take
@@ -631,6 +634,11 @@ static inline void tk_update_ktime_data(struct timekeeper *tk)
 	if (nsec >= NSEC_PER_SEC)
 		seconds++;
 	tk->ktime_sec = seconds;
+
+	/* Update the monotonic raw base */
+	seconds = tk->raw_sec;
+	nsec = (u32)(tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift);
+	tk->tkr_raw.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);
 }
 
 /* must hold timekeeper_lock */
@@ -672,7 +680,6 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
 static void timekeeping_forward_now(struct timekeeper *tk)
 {
 	u64 cycle_now, delta;
-	u64 nsec;
 
 	cycle_now = tk_clock_read(&tk->tkr_mono);
 	delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
@@ -684,10 +691,13 @@ static void timekeeping_forward_now(struct timekeeper *tk)
 	/* If arch requires, add in get_arch_timeoffset() */
 	tk->tkr_mono.xtime_nsec += (u64)arch_gettimeoffset() << tk->tkr_mono.shift;
 
-	tk_normalize_xtime(tk);
 
-	nsec = clocksource_cyc2ns(delta, tk->tkr_raw.mult, tk->tkr_raw.shift);
-	timespec64_add_ns(&tk->raw_time, nsec);
+	tk->tkr_raw.xtime_nsec += delta * tk->tkr_raw.mult;
+
+	/* If arch requires, add in get_arch_timeoffset() */
+	tk->tkr_raw.xtime_nsec += (u64)arch_gettimeoffset() << tk->tkr_raw.shift;
+
+	tk_normalize_xtime(tk);
 }
 
 /**
@@ -1373,19 +1383,18 @@ int timekeeping_notify(struct clocksource *clock)
 void getrawmonotonic64(struct timespec64 *ts)
 {
 	struct timekeeper *tk = &tk_core.timekeeper;
-	struct timespec64 ts64;
 	unsigned long seq;
 	u64 nsecs;
 
 	do {
 		seq = read_seqcount_begin(&tk_core.seq);
+		ts->tv_sec = tk->raw_sec;
 		nsecs = timekeeping_get_ns(&tk->tkr_raw);
-		ts64 = tk->raw_time;
 
 	} while (read_seqcount_retry(&tk_core.seq, seq));
 
-	timespec64_add_ns(&ts64, nsecs);
-	*ts = ts64;
+	ts->tv_nsec = 0;
+	timespec64_add_ns(ts, nsecs);
 }
 EXPORT_SYMBOL(getrawmonotonic64);
 
@@ -1509,8 +1518,7 @@ void __init timekeeping_init(void)
 	tk_setup_internals(tk, clock);
 
 	tk_set_xtime(tk, &now);
-	tk->raw_time.tv_sec = 0;
-	tk->raw_time.tv_nsec = 0;
+	tk->raw_sec = 0;
 	if (boot.tv_sec == 0 && boot.tv_nsec == 0)
 		boot = tk_xtime(tk);
 
@@ -2011,15 +2019,12 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
 	*clock_set |= accumulate_nsecs_to_secs(tk);
 
 	/* Accumulate raw time */
-	tk->tkr_raw.xtime_nsec += (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
 	tk->tkr_raw.xtime_nsec += tk->raw_interval << shift;
 	snsec_per_sec = (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
 	while (tk->tkr_raw.xtime_nsec >= snsec_per_sec) {
 		tk->tkr_raw.xtime_nsec -= snsec_per_sec;
-		tk->raw_time.tv_sec++;
+		tk->raw_sec++;
 	}
-	tk->raw_time.tv_nsec = tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift;
-	tk->tkr_raw.xtime_nsec -= (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
 
 	/* Accumulate error between NTP and clock interval */
 	tk->ntp_error += tk->ntp_tick << shift;
-- 
2.7.4

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

* [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD
  2017-06-21  5:21 [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
  2017-06-21  5:21 ` [PATCH 1/4] time: Clean up CLOCK_MONOTONIC_RAW time handling John Stultz
@ 2017-06-21  5:21 ` John Stultz
  2017-06-21  6:11   ` Paul Mackerras
  2017-06-21  6:15   ` Michael Ellerman
  2017-06-21  5:21 ` [PATCH 3/4] kselftests: timers: Fix inconsistency-check to not ignore first timestamp John Stultz
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 10+ messages in thread
From: John Stultz @ 2017-06-21  5:21 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Marcelo Tosatti,
	Paul Mackerras, Anton Blanchard, Benjamin Herrenschmidt,
	Tony Luck, Michael Ellerman, Fenghua Yu

CONFIG_GENERIC_TIME_VSYSCALL_OLD was introduced five years ago
to allow a transition from the old vsyscall implementations to
the new method (which simplified internal accounting and made
timekeeping more precise).

However, PPC and IA64 have yet to make the transition, despite
in some cases me sending test patches to try to help it along.

http://patches.linaro.org/patch/30501/
http://patches.linaro.org/patch/35412/

If its helpful, my last pass at the patches can be found here:
https://git.linaro.org/people/john.stultz/linux.git dev/oldvsyscall-cleanup

So I think its time to set a deadline and make it clear this
is going away. So this patch adds warnings about this
functionality being dropped. Likely to be in v4.15.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 kernel/time/timekeeping.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 0454bfa..cedafa0 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -516,6 +516,7 @@ static void halt_fast_timekeeper(struct timekeeper *tk)
 }
 
 #ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
+#warning Please contact your maintainers, as GENERIC_TIME_VSYSCALL_OLD compatibity will disappear soon.
 
 static inline void update_vsyscall(struct timekeeper *tk)
 {
-- 
2.7.4

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

* [PATCH 3/4] kselftests: timers: Fix inconsistency-check to not ignore first timestamp
  2017-06-21  5:21 [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
  2017-06-21  5:21 ` [PATCH 1/4] time: Clean up CLOCK_MONOTONIC_RAW time handling John Stultz
  2017-06-21  5:21 ` [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD John Stultz
@ 2017-06-21  5:21 ` John Stultz
  2017-06-21  5:21 ` [PATCH 4/4] kselftests: timers: Add test for frequency step John Stultz
  2017-06-21  5:23 ` [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
  4 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2017-06-21  5:21 UTC (permalink / raw)
  To: lkml
  Cc: Miroslav Lichvar, Thomas Gleixner, Ingo Molnar, Richard Cochran,
	Prarit Bhargava, Stephen Boyd, Shuah Khan, John Stultz

From: Miroslav Lichvar <mlichvar@redhat.com>

When the first timestamp in the list of clock readings was later than
the second timestamp and all other timestamps were in order, the
inconsistency was not reported because the index of the out-of-order
timestamp was equal to the default value.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 tools/testing/selftests/timers/inconsistency-check.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/timers/inconsistency-check.c b/tools/testing/selftests/timers/inconsistency-check.c
index caf1bc9..74c60e8 100644
--- a/tools/testing/selftests/timers/inconsistency-check.c
+++ b/tools/testing/selftests/timers/inconsistency-check.c
@@ -118,7 +118,7 @@ int consistency_test(int clock_type, unsigned long seconds)
 	start_str = ctime(&t);
 
 	while (seconds == -1 || now - then < seconds) {
-		inconsistent = 0;
+		inconsistent = -1;
 
 		/* Fill list */
 		for (i = 0; i < CALLS_PER_LOOP; i++)
@@ -130,7 +130,7 @@ int consistency_test(int clock_type, unsigned long seconds)
 				inconsistent = i;
 
 		/* display inconsistency */
-		if (inconsistent) {
+		if (inconsistent >= 0) {
 			unsigned long long delta;
 
 			printf("\%s\n", start_str);
-- 
2.7.4

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

* [PATCH 4/4] kselftests: timers: Add test for frequency step
  2017-06-21  5:21 [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
                   ` (2 preceding siblings ...)
  2017-06-21  5:21 ` [PATCH 3/4] kselftests: timers: Fix inconsistency-check to not ignore first timestamp John Stultz
@ 2017-06-21  5:21 ` John Stultz
  2017-06-21  5:23 ` [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
  4 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2017-06-21  5:21 UTC (permalink / raw)
  To: lkml
  Cc: Miroslav Lichvar, Thomas Gleixner, Ingo Molnar, Richard Cochran,
	Prarit Bhargava, Stephen Boyd, Shuah Khan, John Stultz

From: Miroslav Lichvar <mlichvar@redhat.com>

This test checks the response of the system clock to frequency
steps made with adjtimex(). The frequency error and stability of
the CLOCK_MONOTONIC clock relative to the CLOCK_MONOTONIC_RAW clock
is measured in two intervals following the step. The test fails if
values from the second interval exceed specified limits.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Shuah Khan <shuah@kernel.org>
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 tools/testing/selftests/timers/Makefile    |   5 +-
 tools/testing/selftests/timers/freq-step.c | 268 +++++++++++++++++++++++++++++
 2 files changed, 271 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/timers/freq-step.c

diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 5fa1d7e9..5801bbe 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -1,6 +1,6 @@
 BUILD_FLAGS = -DKTEST
 CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS)
-LDFLAGS += -lrt -lpthread
+LDFLAGS += -lrt -lpthread -lm
 
 # these are all "safe" tests that don't modify
 # system time or require escalated privileges
@@ -8,7 +8,7 @@ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
 	     inconsistency-check raw_skew threadtest rtctest
 
 TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
-		      skew_consistency clocksource-switch leap-a-day \
+		      skew_consistency clocksource-switch freq-step leap-a-day \
 		      leapcrash set-tai set-2038 set-tz
 
 
@@ -24,6 +24,7 @@ run_destructive_tests: run_tests
 	./change_skew
 	./skew_consistency
 	./clocksource-switch
+	./freq-step
 	./leap-a-day -s -i 10
 	./leapcrash
 	./set-tz
diff --git a/tools/testing/selftests/timers/freq-step.c b/tools/testing/selftests/timers/freq-step.c
new file mode 100644
index 0000000..e8c6183
--- /dev/null
+++ b/tools/testing/selftests/timers/freq-step.c
@@ -0,0 +1,268 @@
+/*
+ * This test checks the response of the system clock to frequency
+ * steps made with adjtimex(). The frequency error and stability of
+ * the CLOCK_MONOTONIC clock relative to the CLOCK_MONOTONIC_RAW clock
+ * is measured in two intervals following the step. The test fails if
+ * values from the second interval exceed specified limits.
+ *
+ * Copyright (C) Miroslav Lichvar <mlichvar@redhat.com>  2017
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <sys/timex.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "../kselftest.h"
+
+#define SAMPLES 100
+#define SAMPLE_READINGS 10
+#define MEAN_SAMPLE_INTERVAL 0.1
+#define STEP_INTERVAL 1.0
+#define MAX_PRECISION 100e-9
+#define MAX_FREQ_ERROR 10e-6
+#define MAX_STDDEV 1000e-9
+
+struct sample {
+	double offset;
+	double time;
+};
+
+static time_t mono_raw_base;
+static time_t mono_base;
+static long user_hz;
+static double precision;
+static double mono_freq_offset;
+
+static double diff_timespec(struct timespec *ts1, struct timespec *ts2)
+{
+	return ts1->tv_sec - ts2->tv_sec + (ts1->tv_nsec - ts2->tv_nsec) / 1e9;
+}
+
+static double get_sample(struct sample *sample)
+{
+	double delay, mindelay = 0.0;
+	struct timespec ts1, ts2, ts3;
+	int i;
+
+	for (i = 0; i < SAMPLE_READINGS; i++) {
+		clock_gettime(CLOCK_MONOTONIC_RAW, &ts1);
+		clock_gettime(CLOCK_MONOTONIC, &ts2);
+		clock_gettime(CLOCK_MONOTONIC_RAW, &ts3);
+
+		ts1.tv_sec -= mono_raw_base;
+		ts2.tv_sec -= mono_base;
+		ts3.tv_sec -= mono_raw_base;
+
+		delay = diff_timespec(&ts3, &ts1);
+		if (delay <= 1e-9) {
+			i--;
+			continue;
+		}
+
+		if (!i || delay < mindelay) {
+			sample->offset = diff_timespec(&ts2, &ts1);
+			sample->offset -= delay / 2.0;
+			sample->time = ts1.tv_sec + ts1.tv_nsec / 1e9;
+			mindelay = delay;
+		}
+	}
+
+	return mindelay;
+}
+
+static void reset_ntp_error(void)
+{
+	struct timex txc;
+
+	txc.modes = ADJ_SETOFFSET;
+	txc.time.tv_sec = 0;
+	txc.time.tv_usec = 0;
+
+	if (adjtimex(&txc) < 0) {
+		perror("[FAIL] adjtimex");
+		ksft_exit_fail();
+	}
+}
+
+static void set_frequency(double freq)
+{
+	struct timex txc;
+	int tick_offset;
+
+	tick_offset = 1e6 * freq / user_hz;
+
+	txc.modes = ADJ_TICK | ADJ_FREQUENCY;
+	txc.tick = 1000000 / user_hz + tick_offset;
+	txc.freq = (1e6 * freq - user_hz * tick_offset) * (1 << 16);
+
+	if (adjtimex(&txc) < 0) {
+		perror("[FAIL] adjtimex");
+		ksft_exit_fail();
+	}
+}
+
+static void regress(struct sample *samples, int n, double *intercept,
+		    double *slope, double *r_stddev, double *r_max)
+{
+	double x, y, r, x_sum, y_sum, xy_sum, x2_sum, r2_sum;
+	int i;
+
+	x_sum = 0.0, y_sum = 0.0, xy_sum = 0.0, x2_sum = 0.0;
+
+	for (i = 0; i < n; i++) {
+		x = samples[i].time;
+		y = samples[i].offset;
+
+		x_sum += x;
+		y_sum += y;
+		xy_sum += x * y;
+		x2_sum += x * x;
+	}
+
+	*slope = (xy_sum - x_sum * y_sum / n) / (x2_sum - x_sum * x_sum / n);
+	*intercept = (y_sum - *slope * x_sum) / n;
+
+	*r_max = 0.0, r2_sum = 0.0;
+
+	for (i = 0; i < n; i++) {
+		x = samples[i].time;
+		y = samples[i].offset;
+		r = fabs(x * *slope + *intercept - y);
+		if (*r_max < r)
+			*r_max = r;
+		r2_sum += r * r;
+	}
+
+	*r_stddev = sqrt(r2_sum / n);
+}
+
+static int run_test(int calibration, double freq_base, double freq_step)
+{
+	struct sample samples[SAMPLES];
+	double intercept, slope, stddev1, max1, stddev2, max2;
+	double freq_error1, freq_error2;
+	int i;
+
+	set_frequency(freq_base);
+
+	for (i = 0; i < 10; i++)
+		usleep(1e6 * MEAN_SAMPLE_INTERVAL / 10);
+
+	reset_ntp_error();
+
+	set_frequency(freq_base + freq_step);
+
+	for (i = 0; i < 10; i++)
+		usleep(rand() % 2000000 * STEP_INTERVAL / 10);
+
+	set_frequency(freq_base);
+
+	for (i = 0; i < SAMPLES; i++) {
+		usleep(rand() % 2000000 * MEAN_SAMPLE_INTERVAL);
+		get_sample(&samples[i]);
+	}
+
+	if (calibration) {
+		regress(samples, SAMPLES, &intercept, &slope, &stddev1, &max1);
+		mono_freq_offset = slope;
+		printf("CLOCK_MONOTONIC_RAW frequency offset: %11.3f ppm\n",
+		       1e6 * mono_freq_offset);
+		return 0;
+	}
+
+	regress(samples, SAMPLES / 2, &intercept, &slope, &stddev1, &max1);
+	freq_error1 = slope * (1.0 - mono_freq_offset) - mono_freq_offset -
+			freq_base;
+
+	regress(samples + SAMPLES / 2, SAMPLES / 2, &intercept, &slope,
+		&stddev2, &max2);
+	freq_error2 = slope * (1.0 - mono_freq_offset) - mono_freq_offset -
+			freq_base;
+
+	printf("%6.0f %+10.3f %6.0f %7.0f %+10.3f %6.0f %7.0f\t",
+	       1e6 * freq_step,
+	       1e6 * freq_error1, 1e9 * stddev1, 1e9 * max1,
+	       1e6 * freq_error2, 1e9 * stddev2, 1e9 * max2);
+
+	if (fabs(freq_error2) > MAX_FREQ_ERROR || stddev2 > MAX_STDDEV) {
+		printf("[FAIL]\n");
+		return 1;
+	}
+
+	printf("[OK]\n");
+	return 0;
+}
+
+static void init_test(void)
+{
+	struct timespec ts;
+	struct sample sample;
+
+	if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts)) {
+		perror("[FAIL] clock_gettime(CLOCK_MONOTONIC_RAW)");
+		ksft_exit_fail();
+	}
+
+	mono_raw_base = ts.tv_sec;
+
+	if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
+		perror("[FAIL] clock_gettime(CLOCK_MONOTONIC)");
+		ksft_exit_fail();
+	}
+
+	mono_base = ts.tv_sec;
+
+	user_hz = sysconf(_SC_CLK_TCK);
+
+	precision = get_sample(&sample) / 2.0;
+	printf("CLOCK_MONOTONIC_RAW+CLOCK_MONOTONIC precision: %.0f ns\t\t",
+	       1e9 * precision);
+
+	if (precision > MAX_PRECISION) {
+		printf("[SKIP]\n");
+		ksft_exit_skip();
+	}
+
+	printf("[OK]\n");
+	srand(ts.tv_sec ^ ts.tv_nsec);
+
+	run_test(1, 0.0, 0.0);
+}
+
+int main(int argc, char **argv)
+{
+	double freq_base, freq_step;
+	int i, j, fails = 0;
+
+	init_test();
+
+	printf("Checking response to frequency step:\n");
+	printf("  Step           1st interval              2nd interval\n");
+	printf("             Freq    Dev     Max       Freq    Dev     Max\n");
+
+	for (i = 2; i >= 0; i--) {
+		for (j = 0; j < 5; j++) {
+			freq_base = (rand() % (1 << 24) - (1 << 23)) / 65536e6;
+			freq_step = 10e-6 * (1 << (6 * i));
+			fails += run_test(0, freq_base, freq_step);
+		}
+	}
+
+	set_frequency(0.0);
+
+	if (fails)
+		ksft_exit_fail();
+
+	ksft_exit_pass();
+}
-- 
2.7.4

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

* Re: [GIT PULL][PATCH 0/4] Timekeeping items for 4.13
  2017-06-21  5:21 [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
                   ` (3 preceding siblings ...)
  2017-06-21  5:21 ` [PATCH 4/4] kselftests: timers: Add test for frequency step John Stultz
@ 2017-06-21  5:23 ` John Stultz
  4 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2017-06-21  5:23 UTC (permalink / raw)
  To: lkml
  Cc: John Stultz, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, Shuah Khan

On Tue, Jun 20, 2017 at 10:21 PM, John Stultz <john.stultz@linaro.org> wrote:
> Just a small set of changes, the biggest changes being the
> MONOTONIC_RAW handling cleanup, and a new kselftest from
> Miroslav. Also a a clear warning deprecating
> CONFIG_GENERIC_TIME_VSYSCALL_OLD, which affects ppc and ia64.

I forgot to note, while it can be intuited from the pull request,
while these are targeted for tip/timers/core, this patchset is based
on the current tip/timers/urgent, as it depends on patches there.

thanks
-john

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

* Re: [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD
  2017-06-21  5:21 ` [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD John Stultz
@ 2017-06-21  6:11   ` Paul Mackerras
  2017-06-21  6:23     ` John Stultz
  2017-06-21  6:15   ` Michael Ellerman
  1 sibling, 1 reply; 10+ messages in thread
From: Paul Mackerras @ 2017-06-21  6:11 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Marcelo Tosatti,
	Anton Blanchard, Benjamin Herrenschmidt, Tony Luck,
	Michael Ellerman, Fenghua Yu

On Tue, Jun 20, 2017 at 10:21:31PM -0700, John Stultz wrote:
> CONFIG_GENERIC_TIME_VSYSCALL_OLD was introduced five years ago
> to allow a transition from the old vsyscall implementations to
> the new method (which simplified internal accounting and made
> timekeeping more precise).
> 
> However, PPC and IA64 have yet to make the transition, despite
> in some cases me sending test patches to try to help it along.

Did you see my patch converting PPC to the new method?  Did you have
any comments on it?

Regards,
Paul.

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

* Re: [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD
  2017-06-21  5:21 ` [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD John Stultz
  2017-06-21  6:11   ` Paul Mackerras
@ 2017-06-21  6:15   ` Michael Ellerman
  1 sibling, 0 replies; 10+ messages in thread
From: Michael Ellerman @ 2017-06-21  6:15 UTC (permalink / raw)
  To: John Stultz, lkml
  Cc: John Stultz, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Marcelo Tosatti,
	Paul Mackerras, Anton Blanchard, Benjamin Herrenschmidt,
	Tony Luck, Fenghua Yu

John Stultz <john.stultz@linaro.org> writes:

> CONFIG_GENERIC_TIME_VSYSCALL_OLD was introduced five years ago
> to allow a transition from the old vsyscall implementations to
> the new method (which simplified internal accounting and made
> timekeeping more precise).
>
> However, PPC and IA64 have yet to make the transition, despite
> in some cases me sending test patches to try to help it along.

Any chance you can review/ack the patch from Paul to convert powerpc
to the new style? :D

cheers

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

* Re: [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD
  2017-06-21  6:11   ` Paul Mackerras
@ 2017-06-21  6:23     ` John Stultz
  0 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2017-06-21  6:23 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: lkml, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Marcelo Tosatti,
	Anton Blanchard, Benjamin Herrenschmidt, Tony Luck,
	Michael Ellerman, Fenghua Yu

On Tue, Jun 20, 2017 at 11:11 PM, Paul Mackerras <paulus@ozlabs.org> wrote:
> On Tue, Jun 20, 2017 at 10:21:31PM -0700, John Stultz wrote:
>> CONFIG_GENERIC_TIME_VSYSCALL_OLD was introduced five years ago
>> to allow a transition from the old vsyscall implementations to
>> the new method (which simplified internal accounting and made
>> timekeeping more precise).
>>
>> However, PPC and IA64 have yet to make the transition, despite
>> in some cases me sending test patches to try to help it along.
>
> Did you see my patch converting PPC to the new method?  Did you have
> any comments on it?

Oh, somehow I missed it!  My apologies. That's great to see! It
roughly looks ok, but I'll need to look at it closer with fresh eyes
(and honestly, its complex enough I'm not sure I will be able to fully
mentally validate it :)

But I'll try to give it a look tomorrow.

thanks
-john

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

* Re: [PATCH 1/4] time: Clean up CLOCK_MONOTONIC_RAW time handling
  2017-06-21  5:21 ` [PATCH 1/4] time: Clean up CLOCK_MONOTONIC_RAW time handling John Stultz
@ 2017-06-21  9:36   ` Will Deacon
  0 siblings, 0 replies; 10+ messages in thread
From: Will Deacon @ 2017-06-21  9:36 UTC (permalink / raw)
  To: John Stultz
  Cc: lkml, Thomas Gleixner, Ingo Molnar, Miroslav Lichvar,
	Richard Cochran, Prarit Bhargava, Stephen Boyd, Kevin Brodsky,
	Daniel Mentz

On Tue, Jun 20, 2017 at 10:21:30PM -0700, John Stultz wrote:
> Now that we fixed the sub-ns handling for CLOCK_MONOTONIC_RAW,
> remove the duplicitive tk->raw_time.tv_nsec, which can be
> stored in tk->tkr_raw.xtime_nsec (similarly to how its handled
> for monotonic time).
> 
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Miroslav Lichvar <mlichvar@redhat.com>
> Cc: Richard Cochran <richardcochran@gmail.com>
> Cc: Prarit Bhargava <prarit@redhat.com>
> Cc: Stephen Boyd <stephen.boyd@linaro.org>
> Cc: Kevin Brodsky <kevin.brodsky@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Daniel Mentz <danielmentz@google.com>
> Tested-by: Daniel Mentz <danielmentz@google.com>
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
>  arch/arm64/kernel/vdso.c            |  6 ++---
>  include/linux/timekeeper_internal.h |  4 ++--
>  kernel/time/timekeeping.c           | 45 ++++++++++++++++++++-----------------
>  3 files changed, 29 insertions(+), 26 deletions(-)
> 
> diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
> index d0cb007..7492d90 100644
> --- a/arch/arm64/kernel/vdso.c
> +++ b/arch/arm64/kernel/vdso.c
> @@ -220,10 +220,8 @@ void update_vsyscall(struct timekeeper *tk)
>  	if (!use_syscall) {
>  		/* tkr_mono.cycle_last == tkr_raw.cycle_last */
>  		vdso_data->cs_cycle_last	= tk->tkr_mono.cycle_last;
> -		vdso_data->raw_time_sec		= tk->raw_time.tv_sec;
> -		vdso_data->raw_time_nsec	= (tk->raw_time.tv_nsec <<
> -						   tk->tkr_raw.shift) +
> -						  tk->tkr_raw.xtime_nsec;
> +		vdso_data->raw_time_sec         = tk->raw_sec;
> +		vdso_data->raw_time_nsec        = tk->tkr_raw.xtime_nsec;
>  		vdso_data->xtime_clock_sec	= tk->xtime_sec;
>  		vdso_data->xtime_clock_nsec	= tk->tkr_mono.xtime_nsec;
>  		vdso_data->cs_mono_mult		= tk->tkr_mono.mult;

For this arm64 bit:

Acked-by: Will Deacon <will.deacon@arm.com>

Will

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

end of thread, other threads:[~2017-06-21  9:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-21  5:21 [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz
2017-06-21  5:21 ` [PATCH 1/4] time: Clean up CLOCK_MONOTONIC_RAW time handling John Stultz
2017-06-21  9:36   ` Will Deacon
2017-06-21  5:21 ` [PATCH 2/4] time: Add warning about imminent deprecation of CONFIG_GENERIC_TIME_VSYSCALL_OLD John Stultz
2017-06-21  6:11   ` Paul Mackerras
2017-06-21  6:23     ` John Stultz
2017-06-21  6:15   ` Michael Ellerman
2017-06-21  5:21 ` [PATCH 3/4] kselftests: timers: Fix inconsistency-check to not ignore first timestamp John Stultz
2017-06-21  5:21 ` [PATCH 4/4] kselftests: timers: Add test for frequency step John Stultz
2017-06-21  5:23 ` [GIT PULL][PATCH 0/4] Timekeeping items for 4.13 John Stultz

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