aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/kernel/vdso.c6
-rw-r--r--include/linux/timekeeper_internal.h4
-rw-r--r--kernel/time/timekeeping.c46
-rw-r--r--tools/testing/selftests/timers/Makefile5
-rw-r--r--tools/testing/selftests/timers/freq-step.c268
-rw-r--r--tools/testing/selftests/timers/inconsistency-check.c4
6 files changed, 303 insertions, 30 deletions
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index d0cb007fa482..7492d9009610 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -220,10 +220,8 @@ void update_vsyscall(struct timekeeper *tk)
220 if (!use_syscall) { 220 if (!use_syscall) {
221 /* tkr_mono.cycle_last == tkr_raw.cycle_last */ 221 /* tkr_mono.cycle_last == tkr_raw.cycle_last */
222 vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; 222 vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last;
223 vdso_data->raw_time_sec = tk->raw_time.tv_sec; 223 vdso_data->raw_time_sec = tk->raw_sec;
224 vdso_data->raw_time_nsec = (tk->raw_time.tv_nsec << 224 vdso_data->raw_time_nsec = tk->tkr_raw.xtime_nsec;
225 tk->tkr_raw.shift) +
226 tk->tkr_raw.xtime_nsec;
227 vdso_data->xtime_clock_sec = tk->xtime_sec; 225 vdso_data->xtime_clock_sec = tk->xtime_sec;
228 vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; 226 vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec;
229 vdso_data->cs_mono_mult = tk->tkr_mono.mult; 227 vdso_data->cs_mono_mult = tk->tkr_mono.mult;
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index f7043ccca81c..0a0a53daf2a2 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -51,7 +51,7 @@ struct tk_read_base {
51 * @clock_was_set_seq: The sequence number of clock was set events 51 * @clock_was_set_seq: The sequence number of clock was set events
52 * @cs_was_changed_seq: The sequence number of clocksource change events 52 * @cs_was_changed_seq: The sequence number of clocksource change events
53 * @next_leap_ktime: CLOCK_MONOTONIC time value of a pending leap-second 53 * @next_leap_ktime: CLOCK_MONOTONIC time value of a pending leap-second
54 * @raw_time: Monotonic raw base time in timespec64 format 54 * @raw_sec: CLOCK_MONOTONIC_RAW time in seconds
55 * @cycle_interval: Number of clock cycles in one NTP interval 55 * @cycle_interval: Number of clock cycles in one NTP interval
56 * @xtime_interval: Number of clock shifted nano seconds in one NTP 56 * @xtime_interval: Number of clock shifted nano seconds in one NTP
57 * interval. 57 * interval.
@@ -93,7 +93,7 @@ struct timekeeper {
93 unsigned int clock_was_set_seq; 93 unsigned int clock_was_set_seq;
94 u8 cs_was_changed_seq; 94 u8 cs_was_changed_seq;
95 ktime_t next_leap_ktime; 95 ktime_t next_leap_ktime;
96 struct timespec64 raw_time; 96 u64 raw_sec;
97 97
98 /* The following members are for timekeeping internal use */ 98 /* The following members are for timekeeping internal use */
99 u64 cycle_interval; 99 u64 cycle_interval;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b602c48cb841..cedafa008de5 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -72,6 +72,10 @@ static inline void tk_normalize_xtime(struct timekeeper *tk)
72 tk->tkr_mono.xtime_nsec -= (u64)NSEC_PER_SEC << tk->tkr_mono.shift; 72 tk->tkr_mono.xtime_nsec -= (u64)NSEC_PER_SEC << tk->tkr_mono.shift;
73 tk->xtime_sec++; 73 tk->xtime_sec++;
74 } 74 }
75 while (tk->tkr_raw.xtime_nsec >= ((u64)NSEC_PER_SEC << tk->tkr_raw.shift)) {
76 tk->tkr_raw.xtime_nsec -= (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
77 tk->raw_sec++;
78 }
75} 79}
76 80
77static inline struct timespec64 tk_xtime(struct timekeeper *tk) 81static inline struct timespec64 tk_xtime(struct timekeeper *tk)
@@ -285,12 +289,14 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
285 /* if changing clocks, convert xtime_nsec shift units */ 289 /* if changing clocks, convert xtime_nsec shift units */
286 if (old_clock) { 290 if (old_clock) {
287 int shift_change = clock->shift - old_clock->shift; 291 int shift_change = clock->shift - old_clock->shift;
288 if (shift_change < 0) 292 if (shift_change < 0) {
289 tk->tkr_mono.xtime_nsec >>= -shift_change; 293 tk->tkr_mono.xtime_nsec >>= -shift_change;
290 else 294 tk->tkr_raw.xtime_nsec >>= -shift_change;
295 } else {
291 tk->tkr_mono.xtime_nsec <<= shift_change; 296 tk->tkr_mono.xtime_nsec <<= shift_change;
297 tk->tkr_raw.xtime_nsec <<= shift_change;
298 }
292 } 299 }
293 tk->tkr_raw.xtime_nsec = 0;
294 300
295 tk->tkr_mono.shift = clock->shift; 301 tk->tkr_mono.shift = clock->shift;
296 tk->tkr_raw.shift = clock->shift; 302 tk->tkr_raw.shift = clock->shift;
@@ -510,6 +516,7 @@ static void halt_fast_timekeeper(struct timekeeper *tk)
510} 516}
511 517
512#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD 518#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
519#warning Please contact your maintainers, as GENERIC_TIME_VSYSCALL_OLD compatibity will disappear soon.
513 520
514static inline void update_vsyscall(struct timekeeper *tk) 521static inline void update_vsyscall(struct timekeeper *tk)
515{ 522{
@@ -619,9 +626,6 @@ static inline void tk_update_ktime_data(struct timekeeper *tk)
619 nsec = (u32) tk->wall_to_monotonic.tv_nsec; 626 nsec = (u32) tk->wall_to_monotonic.tv_nsec;
620 tk->tkr_mono.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec); 627 tk->tkr_mono.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);
621 628
622 /* Update the monotonic raw base */
623 tk->tkr_raw.base = timespec64_to_ktime(tk->raw_time);
624
625 /* 629 /*
626 * The sum of the nanoseconds portions of xtime and 630 * The sum of the nanoseconds portions of xtime and
627 * wall_to_monotonic can be greater/equal one second. Take 631 * wall_to_monotonic can be greater/equal one second. Take
@@ -631,6 +635,11 @@ static inline void tk_update_ktime_data(struct timekeeper *tk)
631 if (nsec >= NSEC_PER_SEC) 635 if (nsec >= NSEC_PER_SEC)
632 seconds++; 636 seconds++;
633 tk->ktime_sec = seconds; 637 tk->ktime_sec = seconds;
638
639 /* Update the monotonic raw base */
640 seconds = tk->raw_sec;
641 nsec = (u32)(tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift);
642 tk->tkr_raw.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);
634} 643}
635 644
636/* must hold timekeeper_lock */ 645/* must hold timekeeper_lock */
@@ -672,7 +681,6 @@ static void timekeeping_update(struct timekeeper *tk, unsigned int action)
672static void timekeeping_forward_now(struct timekeeper *tk) 681static void timekeeping_forward_now(struct timekeeper *tk)
673{ 682{
674 u64 cycle_now, delta; 683 u64 cycle_now, delta;
675 u64 nsec;
676 684
677 cycle_now = tk_clock_read(&tk->tkr_mono); 685 cycle_now = tk_clock_read(&tk->tkr_mono);
678 delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask); 686 delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask);
@@ -684,10 +692,13 @@ static void timekeeping_forward_now(struct timekeeper *tk)
684 /* If arch requires, add in get_arch_timeoffset() */ 692 /* If arch requires, add in get_arch_timeoffset() */
685 tk->tkr_mono.xtime_nsec += (u64)arch_gettimeoffset() << tk->tkr_mono.shift; 693 tk->tkr_mono.xtime_nsec += (u64)arch_gettimeoffset() << tk->tkr_mono.shift;
686 694
687 tk_normalize_xtime(tk);
688 695
689 nsec = clocksource_cyc2ns(delta, tk->tkr_raw.mult, tk->tkr_raw.shift); 696 tk->tkr_raw.xtime_nsec += delta * tk->tkr_raw.mult;
690 timespec64_add_ns(&tk->raw_time, nsec); 697
698 /* If arch requires, add in get_arch_timeoffset() */
699 tk->tkr_raw.xtime_nsec += (u64)arch_gettimeoffset() << tk->tkr_raw.shift;
700
701 tk_normalize_xtime(tk);
691} 702}
692 703
693/** 704/**
@@ -1373,19 +1384,18 @@ int timekeeping_notify(struct clocksource *clock)
1373void getrawmonotonic64(struct timespec64 *ts) 1384void getrawmonotonic64(struct timespec64 *ts)
1374{ 1385{
1375 struct timekeeper *tk = &tk_core.timekeeper; 1386 struct timekeeper *tk = &tk_core.timekeeper;
1376 struct timespec64 ts64;
1377 unsigned long seq; 1387 unsigned long seq;
1378 u64 nsecs; 1388 u64 nsecs;
1379 1389
1380 do { 1390 do {
1381 seq = read_seqcount_begin(&tk_core.seq); 1391 seq = read_seqcount_begin(&tk_core.seq);
1392 ts->tv_sec = tk->raw_sec;
1382 nsecs = timekeeping_get_ns(&tk->tkr_raw); 1393 nsecs = timekeeping_get_ns(&tk->tkr_raw);
1383 ts64 = tk->raw_time;
1384 1394
1385 } while (read_seqcount_retry(&tk_core.seq, seq)); 1395 } while (read_seqcount_retry(&tk_core.seq, seq));
1386 1396
1387 timespec64_add_ns(&ts64, nsecs); 1397 ts->tv_nsec = 0;
1388 *ts = ts64; 1398 timespec64_add_ns(ts, nsecs);
1389} 1399}
1390EXPORT_SYMBOL(getrawmonotonic64); 1400EXPORT_SYMBOL(getrawmonotonic64);
1391 1401
@@ -1509,8 +1519,7 @@ void __init timekeeping_init(void)
1509 tk_setup_internals(tk, clock); 1519 tk_setup_internals(tk, clock);
1510 1520
1511 tk_set_xtime(tk, &now); 1521 tk_set_xtime(tk, &now);
1512 tk->raw_time.tv_sec = 0; 1522 tk->raw_sec = 0;
1513 tk->raw_time.tv_nsec = 0;
1514 if (boot.tv_sec == 0 && boot.tv_nsec == 0) 1523 if (boot.tv_sec == 0 && boot.tv_nsec == 0)
1515 boot = tk_xtime(tk); 1524 boot = tk_xtime(tk);
1516 1525
@@ -2011,15 +2020,12 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
2011 *clock_set |= accumulate_nsecs_to_secs(tk); 2020 *clock_set |= accumulate_nsecs_to_secs(tk);
2012 2021
2013 /* Accumulate raw time */ 2022 /* Accumulate raw time */
2014 tk->tkr_raw.xtime_nsec += (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
2015 tk->tkr_raw.xtime_nsec += tk->raw_interval << shift; 2023 tk->tkr_raw.xtime_nsec += tk->raw_interval << shift;
2016 snsec_per_sec = (u64)NSEC_PER_SEC << tk->tkr_raw.shift; 2024 snsec_per_sec = (u64)NSEC_PER_SEC << tk->tkr_raw.shift;
2017 while (tk->tkr_raw.xtime_nsec >= snsec_per_sec) { 2025 while (tk->tkr_raw.xtime_nsec >= snsec_per_sec) {
2018 tk->tkr_raw.xtime_nsec -= snsec_per_sec; 2026 tk->tkr_raw.xtime_nsec -= snsec_per_sec;
2019 tk->raw_time.tv_sec++; 2027 tk->raw_sec++;
2020 } 2028 }
2021 tk->raw_time.tv_nsec = tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift;
2022 tk->tkr_raw.xtime_nsec -= (u64)tk->raw_time.tv_nsec << tk->tkr_raw.shift;
2023 2029
2024 /* Accumulate error between NTP and clock interval */ 2030 /* Accumulate error between NTP and clock interval */
2025 tk->ntp_error += tk->ntp_tick << shift; 2031 tk->ntp_error += tk->ntp_tick << shift;
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 5fa1d7e9a915..5801bbefbe89 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -1,6 +1,6 @@
1BUILD_FLAGS = -DKTEST 1BUILD_FLAGS = -DKTEST
2CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS) 2CFLAGS += -O3 -Wl,-no-as-needed -Wall $(BUILD_FLAGS)
3LDFLAGS += -lrt -lpthread 3LDFLAGS += -lrt -lpthread -lm
4 4
5# these are all "safe" tests that don't modify 5# these are all "safe" tests that don't modify
6# system time or require escalated privileges 6# system time or require escalated privileges
@@ -8,7 +8,7 @@ TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
8 inconsistency-check raw_skew threadtest rtctest 8 inconsistency-check raw_skew threadtest rtctest
9 9
10TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \ 10TEST_GEN_PROGS_EXTENDED = alarmtimer-suspend valid-adjtimex adjtick change_skew \
11 skew_consistency clocksource-switch leap-a-day \ 11 skew_consistency clocksource-switch freq-step leap-a-day \
12 leapcrash set-tai set-2038 set-tz 12 leapcrash set-tai set-2038 set-tz
13 13
14 14
@@ -24,6 +24,7 @@ run_destructive_tests: run_tests
24 ./change_skew 24 ./change_skew
25 ./skew_consistency 25 ./skew_consistency
26 ./clocksource-switch 26 ./clocksource-switch
27 ./freq-step
27 ./leap-a-day -s -i 10 28 ./leap-a-day -s -i 10
28 ./leapcrash 29 ./leapcrash
29 ./set-tz 30 ./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 000000000000..e8c61830825a
--- /dev/null
+++ b/tools/testing/selftests/timers/freq-step.c
@@ -0,0 +1,268 @@
1/*
2 * This test checks the response of the system clock to frequency
3 * steps made with adjtimex(). The frequency error and stability of
4 * the CLOCK_MONOTONIC clock relative to the CLOCK_MONOTONIC_RAW clock
5 * is measured in two intervals following the step. The test fails if
6 * values from the second interval exceed specified limits.
7 *
8 * Copyright (C) Miroslav Lichvar <mlichvar@redhat.com> 2017
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#include <math.h>
21#include <stdio.h>
22#include <sys/timex.h>
23#include <time.h>
24#include <unistd.h>
25
26#include "../kselftest.h"
27
28#define SAMPLES 100
29#define SAMPLE_READINGS 10
30#define MEAN_SAMPLE_INTERVAL 0.1
31#define STEP_INTERVAL 1.0
32#define MAX_PRECISION 100e-9
33#define MAX_FREQ_ERROR 10e-6
34#define MAX_STDDEV 1000e-9
35
36struct sample {
37 double offset;
38 double time;
39};
40
41static time_t mono_raw_base;
42static time_t mono_base;
43static long user_hz;
44static double precision;
45static double mono_freq_offset;
46
47static double diff_timespec(struct timespec *ts1, struct timespec *ts2)
48{
49 return ts1->tv_sec - ts2->tv_sec + (ts1->tv_nsec - ts2->tv_nsec) / 1e9;
50}
51
52static double get_sample(struct sample *sample)
53{
54 double delay, mindelay = 0.0;
55 struct timespec ts1, ts2, ts3;
56 int i;
57
58 for (i = 0; i < SAMPLE_READINGS; i++) {
59 clock_gettime(CLOCK_MONOTONIC_RAW, &ts1);
60 clock_gettime(CLOCK_MONOTONIC, &ts2);
61 clock_gettime(CLOCK_MONOTONIC_RAW, &ts3);
62
63 ts1.tv_sec -= mono_raw_base;
64 ts2.tv_sec -= mono_base;
65 ts3.tv_sec -= mono_raw_base;
66
67 delay = diff_timespec(&ts3, &ts1);
68 if (delay <= 1e-9) {
69 i--;
70 continue;
71 }
72
73 if (!i || delay < mindelay) {
74 sample->offset = diff_timespec(&ts2, &ts1);
75 sample->offset -= delay / 2.0;
76 sample->time = ts1.tv_sec + ts1.tv_nsec / 1e9;
77 mindelay = delay;
78 }
79 }
80
81 return mindelay;
82}
83
84static void reset_ntp_error(void)
85{
86 struct timex txc;
87
88 txc.modes = ADJ_SETOFFSET;
89 txc.time.tv_sec = 0;
90 txc.time.tv_usec = 0;
91
92 if (adjtimex(&txc) < 0) {
93 perror("[FAIL] adjtimex");
94 ksft_exit_fail();
95 }
96}
97
98static void set_frequency(double freq)
99{
100 struct timex txc;
101 int tick_offset;
102
103 tick_offset = 1e6 * freq / user_hz;
104
105 txc.modes = ADJ_TICK | ADJ_FREQUENCY;
106 txc.tick = 1000000 / user_hz + tick_offset;
107 txc.freq = (1e6 * freq - user_hz * tick_offset) * (1 << 16);
108
109 if (adjtimex(&txc) < 0) {
110 perror("[FAIL] adjtimex");
111 ksft_exit_fail();
112 }
113}
114
115static void regress(struct sample *samples, int n, double *intercept,
116 double *slope, double *r_stddev, double *r_max)
117{
118 double x, y, r, x_sum, y_sum, xy_sum, x2_sum, r2_sum;
119 int i;
120
121 x_sum = 0.0, y_sum = 0.0, xy_sum = 0.0, x2_sum = 0.0;
122
123 for (i = 0; i < n; i++) {
124 x = samples[i].time;
125 y = samples[i].offset;
126
127 x_sum += x;
128 y_sum += y;
129 xy_sum += x * y;
130 x2_sum += x * x;
131 }
132
133 *slope = (xy_sum - x_sum * y_sum / n) / (x2_sum - x_sum * x_sum / n);
134 *intercept = (y_sum - *slope * x_sum) / n;
135
136 *r_max = 0.0, r2_sum = 0.0;
137
138 for (i = 0; i < n; i++) {
139 x = samples[i].time;
140 y = samples[i].offset;
141 r = fabs(x * *slope + *intercept - y);
142 if (*r_max < r)
143 *r_max = r;
144 r2_sum += r * r;
145 }
146
147 *r_stddev = sqrt(r2_sum / n);
148}
149
150static int run_test(int calibration, double freq_base, double freq_step)
151{
152 struct sample samples[SAMPLES];
153 double intercept, slope, stddev1, max1, stddev2, max2;
154 double freq_error1, freq_error2;
155 int i;
156
157 set_frequency(freq_base);
158
159 for (i = 0; i < 10; i++)
160 usleep(1e6 * MEAN_SAMPLE_INTERVAL / 10);
161
162 reset_ntp_error();
163
164 set_frequency(freq_base + freq_step);
165
166 for (i = 0; i < 10; i++)
167 usleep(rand() % 2000000 * STEP_INTERVAL / 10);
168
169 set_frequency(freq_base);
170
171 for (i = 0; i < SAMPLES; i++) {
172 usleep(rand() % 2000000 * MEAN_SAMPLE_INTERVAL);
173 get_sample(&samples[i]);
174 }
175
176 if (calibration) {
177 regress(samples, SAMPLES, &intercept, &slope, &stddev1, &max1);
178 mono_freq_offset = slope;
179 printf("CLOCK_MONOTONIC_RAW frequency offset: %11.3f ppm\n",
180 1e6 * mono_freq_offset);
181 return 0;
182 }
183
184 regress(samples, SAMPLES / 2, &intercept, &slope, &stddev1, &max1);
185 freq_error1 = slope * (1.0 - mono_freq_offset) - mono_freq_offset -
186 freq_base;
187
188 regress(samples + SAMPLES / 2, SAMPLES / 2, &intercept, &slope,
189 &stddev2, &max2);
190 freq_error2 = slope * (1.0 - mono_freq_offset) - mono_freq_offset -
191 freq_base;
192
193 printf("%6.0f %+10.3f %6.0f %7.0f %+10.3f %6.0f %7.0f\t",
194 1e6 * freq_step,
195 1e6 * freq_error1, 1e9 * stddev1, 1e9 * max1,
196 1e6 * freq_error2, 1e9 * stddev2, 1e9 * max2);
197
198 if (fabs(freq_error2) > MAX_FREQ_ERROR || stddev2 > MAX_STDDEV) {
199 printf("[FAIL]\n");
200 return 1;
201 }
202
203 printf("[OK]\n");
204 return 0;
205}
206
207static void init_test(void)
208{
209 struct timespec ts;
210 struct sample sample;
211
212 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts)) {
213 perror("[FAIL] clock_gettime(CLOCK_MONOTONIC_RAW)");
214 ksft_exit_fail();
215 }
216
217 mono_raw_base = ts.tv_sec;
218
219 if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
220 perror("[FAIL] clock_gettime(CLOCK_MONOTONIC)");
221 ksft_exit_fail();
222 }
223
224 mono_base = ts.tv_sec;
225
226 user_hz = sysconf(_SC_CLK_TCK);
227
228 precision = get_sample(&sample) / 2.0;
229 printf("CLOCK_MONOTONIC_RAW+CLOCK_MONOTONIC precision: %.0f ns\t\t",
230 1e9 * precision);
231
232 if (precision > MAX_PRECISION) {
233 printf("[SKIP]\n");
234 ksft_exit_skip();
235 }
236
237 printf("[OK]\n");
238 srand(ts.tv_sec ^ ts.tv_nsec);
239
240 run_test(1, 0.0, 0.0);
241}
242
243int main(int argc, char **argv)
244{
245 double freq_base, freq_step;
246 int i, j, fails = 0;
247
248 init_test();
249
250 printf("Checking response to frequency step:\n");
251 printf(" Step 1st interval 2nd interval\n");
252 printf(" Freq Dev Max Freq Dev Max\n");
253
254 for (i = 2; i >= 0; i--) {
255 for (j = 0; j < 5; j++) {
256 freq_base = (rand() % (1 << 24) - (1 << 23)) / 65536e6;
257 freq_step = 10e-6 * (1 << (6 * i));
258 fails += run_test(0, freq_base, freq_step);
259 }
260 }
261
262 set_frequency(0.0);
263
264 if (fails)
265 ksft_exit_fail();
266
267 ksft_exit_pass();
268}
diff --git a/tools/testing/selftests/timers/inconsistency-check.c b/tools/testing/selftests/timers/inconsistency-check.c
index caf1bc9257c4..74c60e8759a0 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)
118 start_str = ctime(&t); 118 start_str = ctime(&t);
119 119
120 while (seconds == -1 || now - then < seconds) { 120 while (seconds == -1 || now - then < seconds) {
121 inconsistent = 0; 121 inconsistent = -1;
122 122
123 /* Fill list */ 123 /* Fill list */
124 for (i = 0; i < CALLS_PER_LOOP; i++) 124 for (i = 0; i < CALLS_PER_LOOP; i++)
@@ -130,7 +130,7 @@ int consistency_test(int clock_type, unsigned long seconds)
130 inconsistent = i; 130 inconsistent = i;
131 131
132 /* display inconsistency */ 132 /* display inconsistency */
133 if (inconsistent) { 133 if (inconsistent >= 0) {
134 unsigned long long delta; 134 unsigned long long delta;
135 135
136 printf("\%s\n", start_str); 136 printf("\%s\n", start_str);