diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-18 16:23:56 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-18 16:23:56 -0700 |
| commit | 3b4128b9f374b4219eb716f4ad8a307bc7eb3d84 (patch) | |
| tree | e9489db7a4ab524e7849fb70a3cc47a08700e1ad /tools/testing | |
| parent | b0239dd672306ad242545f793132938847f17e53 (diff) | |
| parent | 4fa377c19e111c539a530a8200996b911ceff9ff (diff) | |
Merge tag 'timers-core-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull timer and timekeeping core updates from Thomas Gleixner:
- Fix a subtly inconsistency in the timekeeping code, which fails to
account for the monotonicity adjustment in ntp_error.
For small changes of the clocksource multiplicator (+/-1) which are
typically used by the NTP PLL this is hard to observe. But for larger
adjustments, e.g. caused by a direct frequency setting through
adjtimex() the one-time uncompensated offset is significant.
Cure this by adjusting ntp_error with the resulting offset so that
the discrepancy is smoothed away over time
- Make tick length calculations correct in NTP.
The timekeeping core takes the quantisation of the clocksource into
account when calculating the tick length to compensate for the
deviation of the nominal NTP_INTERVAL_LENGTH.
While timekeeping gets this right, NTP is not aware of that, which
means it operates on the nominal value and not on the actual value
which is determined by the clock source frequency. The rounding of a
coarse clocksource like the ACPI PM timer results in a +127 PPM
deviation.
Cure this by exposing the deviation to the NTP code so that it can
operate on the same data as the timekeeping core. This is purely
kernel internal. User space still sees the nominal tick lenght via
adjtimex().
- The accuracy of the NTP adjustments is fairly approximate as the code
assumes that the invocations are precisely in NTP interval frequency
ticks and the final adjustment can over and under-run.
Cure this by adjusting ntp_error by the intended skew on each tick to
achieve the desired rate.
- Handle the two competing skews of time offset and time adjustment
correctly by calculating the conflict portion between the skews and
adjusting both accordingly.
- A set of updates and improvements for the selftests
- The usual small fixes and improvements all over the place
* tag 'timers-core-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (58 commits)
selftests: timers: nsleep-lat: Check all calls to clock_nanosleep() and clock_gettime()
selftests: timers: nsleep-lat: Reuse kselftest error numbers
selftests: timers: nsleep-lat: Explicitly list the tested clocks
selftests: timers: nsleep-lat: Use NSEC_PER_MSEC define for unreasonable latency
selftests: timers: nanosleep: Report each test separately
selftests: timers: nanosleep: Explicitly handle timer_delete() failure
selftests: timers: nanosleep: Move all single clock tests out of the loop in main()
selftests: timers: nanosleep: Reuse kselftest error numbers
selftests: timers: nanosleep: Explicitly list the tested clocks
selftests: timers: nanosleep: Drop output alignment
selftests: timers: Use clock_name() and constants from clock-helpers.h
selftests: Add clock-helpers.h
timer_list: Use ktime_t over nanoseconds
timer_list: Use standard 'long long' format placeholders
hrtimer: Add a lockdep assertion to hrtimer_update_base()
timekeeping: Use u32 for clock_was_set_seq
timekeeping: Rename clockid_aux_valid() to clockid_is_aux_clock()
hrtimer: Account nr_retries on recovered interrupt retries
timers/itimer: Zero-init old itimerval before copy to userspace
nohz: Replace dead select with choice default
...
Diffstat (limited to 'tools/testing')
| -rw-r--r-- | tools/testing/selftests/clock-helpers.h | 76 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/Makefile | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/adjtick.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/alarmtimer-suspend.c | 37 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/inconsistency-check.c | 37 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/leap-a-day.c | 21 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/mqueue-lat.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/nanosleep.c | 144 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/nsleep-lat.c | 101 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/posix_timers.c | 34 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/raw_skew.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/set-2038.c | 2 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/set-timer-lat.c | 40 | ||||
| -rw-r--r-- | tools/testing/selftests/timers/valid-adjtimex.c | 2 |
14 files changed, 218 insertions, 284 deletions
diff --git a/tools/testing/selftests/clock-helpers.h b/tools/testing/selftests/clock-helpers.h new file mode 100644 index 000000000000..01451f538e71 --- /dev/null +++ b/tools/testing/selftests/clock-helpers.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __CLOCK_HELPERS_H +#define __CLOCK_HELPERS_H + +#include <sys/types.h> +#include <time.h> + +#define MSEC_PER_SEC 1000LL +#define USEC_PER_MSEC 1000LL +#define NSEC_PER_USEC 1000LL +#define NSEC_PER_MSEC 1000000LL +#define USEC_PER_SEC 1000000LL +#define NSEC_PER_SEC 1000000000LL +#define PSEC_PER_SEC 1000000000000LL +#define FSEC_PER_SEC 1000000000000000LL + +#ifndef CLOCK_AUX +#define CLOCK_AUX 16 +#endif + +#ifndef MAX_AUX_CLOCKS +#define MAX_AUX_CLOCKS 8 +#endif + +#ifndef CLOCK_AUX_LAST +#define CLOCK_AUX_LAST (CLOCK_AUX + MAX_AUX_CLOCKS - 1) +#endif + +__attribute__((unused)) +static inline const char *clock_name(clockid_t clockid) +{ + switch (clockid) { + case CLOCK_REALTIME: + return "CLOCK_REALTIME"; + case CLOCK_MONOTONIC: + return "CLOCK_MONOTONIC"; + case CLOCK_PROCESS_CPUTIME_ID: + return "CLOCK_PROCESS_CPUTIME_ID"; + case CLOCK_THREAD_CPUTIME_ID: + return "CLOCK_THREAD_CPUTIME_ID"; + case CLOCK_MONOTONIC_RAW: + return "CLOCK_MONOTONIC_RAW"; + case CLOCK_REALTIME_COARSE: + return "CLOCK_REALTIME_COARSE"; + case CLOCK_MONOTONIC_COARSE: + return "CLOCK_MONOTONIC_COARSE"; + case CLOCK_BOOTTIME: + return "CLOCK_BOOTTIME"; + case CLOCK_REALTIME_ALARM: + return "CLOCK_REALTIME_ALARM"; + case CLOCK_BOOTTIME_ALARM: + return "CLOCK_BOOTTIME_ALARM"; + case CLOCK_TAI: + return "CLOCK_TAI"; + case CLOCK_AUX + 0: + return "CLOCK_AUX0"; + case CLOCK_AUX + 1: + return "CLOCK_AUX1"; + case CLOCK_AUX + 2: + return "CLOCK_AUX2"; + case CLOCK_AUX + 3: + return "CLOCK_AUX3"; + case CLOCK_AUX + 4: + return "CLOCK_AUX4"; + case CLOCK_AUX + 5: + return "CLOCK_AUX5"; + case CLOCK_AUX + 6: + return "CLOCK_AUX6"; + case CLOCK_AUX + 7: + return "CLOCK_AUX7"; + }; + return "UNKNOWN_CLOCKID"; +} + +#endif /* __CLOCK_HELPERS_H */ diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile index 32203593c62e..0e73a16874c4 100644 --- a/tools/testing/selftests/timers/Makefile +++ b/tools/testing/selftests/timers/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -CFLAGS += -O3 -Wl,-no-as-needed -Wall -I $(top_srcdir) +CFLAGS += -O3 -Wl,-no-as-needed -Wall LDLIBS += -lrt -lpthread -lm # these are all "safe" tests that don't modify diff --git a/tools/testing/selftests/timers/adjtick.c b/tools/testing/selftests/timers/adjtick.c index 5b3ef708d6e9..68009a6d6de8 100644 --- a/tools/testing/selftests/timers/adjtick.c +++ b/tools/testing/selftests/timers/adjtick.c @@ -22,8 +22,8 @@ #include <sys/time.h> #include <sys/timex.h> #include <time.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" #define MILLION 1000000 diff --git a/tools/testing/selftests/timers/alarmtimer-suspend.c b/tools/testing/selftests/timers/alarmtimer-suspend.c index aa66c805f6a4..120b3ce8b39e 100644 --- a/tools/testing/selftests/timers/alarmtimer-suspend.c +++ b/tools/testing/selftests/timers/alarmtimer-suspend.c @@ -28,8 +28,8 @@ #include <signal.h> #include <stdlib.h> #include <pthread.h> -#include <include/vdso/time64.h> #include <errno.h> +#include "clock-helpers.h" #include "kselftest.h" #define UNREASONABLE_LAT (NSEC_PER_SEC * 5) /* hopefully we resume in 5 secs */ @@ -39,37 +39,6 @@ int alarmcount; int alarm_clock_id; struct timespec start_time; - -char *clockstring(int clockid) -{ - switch (clockid) { - case CLOCK_REALTIME: - return "CLOCK_REALTIME"; - case CLOCK_MONOTONIC: - return "CLOCK_MONOTONIC"; - case CLOCK_PROCESS_CPUTIME_ID: - return "CLOCK_PROCESS_CPUTIME_ID"; - case CLOCK_THREAD_CPUTIME_ID: - return "CLOCK_THREAD_CPUTIME_ID"; - case CLOCK_MONOTONIC_RAW: - return "CLOCK_MONOTONIC_RAW"; - case CLOCK_REALTIME_COARSE: - return "CLOCK_REALTIME_COARSE"; - case CLOCK_MONOTONIC_COARSE: - return "CLOCK_MONOTONIC_COARSE"; - case CLOCK_BOOTTIME: - return "CLOCK_BOOTTIME"; - case CLOCK_REALTIME_ALARM: - return "CLOCK_REALTIME_ALARM"; - case CLOCK_BOOTTIME_ALARM: - return "CLOCK_BOOTTIME_ALARM"; - case CLOCK_TAI: - return "CLOCK_TAI"; - } - return "UNKNOWN_CLOCKID"; -} - - long long timespec_sub(struct timespec a, struct timespec b) { long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; @@ -129,12 +98,12 @@ int main(void) alarmcount = 0; if (timer_create(alarm_clock_id, &se, &tm1) == -1) { printf("timer_create failed, %s unsupported?: %s\n", - clockstring(alarm_clock_id), strerror(errno)); + clock_name(alarm_clock_id), strerror(errno)); break; } clock_gettime(alarm_clock_id, &start_time); - printf("Start time (%s): %ld:%ld\n", clockstring(alarm_clock_id), + printf("Start time (%s): %ld:%ld\n", clock_name(alarm_clock_id), start_time.tv_sec, start_time.tv_nsec); printf("Setting alarm for every %i seconds\n", SUSPEND_SECS); its1.it_value = start_time; diff --git a/tools/testing/selftests/timers/inconsistency-check.c b/tools/testing/selftests/timers/inconsistency-check.c index e53e63e18683..d7982ac4bd18 100644 --- a/tools/testing/selftests/timers/inconsistency-check.c +++ b/tools/testing/selftests/timers/inconsistency-check.c @@ -28,7 +28,7 @@ #include <sys/timex.h> #include <string.h> #include <signal.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" /* CLOCK_HWSPECIFIC == CLOCK_SGI_CYCLE (Deprecated) */ @@ -36,35 +36,6 @@ #define CALLS_PER_LOOP 64 -char *clockstring(int clockid) -{ - switch (clockid) { - case CLOCK_REALTIME: - return "CLOCK_REALTIME"; - case CLOCK_MONOTONIC: - return "CLOCK_MONOTONIC"; - case CLOCK_PROCESS_CPUTIME_ID: - return "CLOCK_PROCESS_CPUTIME_ID"; - case CLOCK_THREAD_CPUTIME_ID: - return "CLOCK_THREAD_CPUTIME_ID"; - case CLOCK_MONOTONIC_RAW: - return "CLOCK_MONOTONIC_RAW"; - case CLOCK_REALTIME_COARSE: - return "CLOCK_REALTIME_COARSE"; - case CLOCK_MONOTONIC_COARSE: - return "CLOCK_MONOTONIC_COARSE"; - case CLOCK_BOOTTIME: - return "CLOCK_BOOTTIME"; - case CLOCK_REALTIME_ALARM: - return "CLOCK_REALTIME_ALARM"; - case CLOCK_BOOTTIME_ALARM: - return "CLOCK_BOOTTIME_ALARM"; - case CLOCK_TAI: - return "CLOCK_TAI"; - } - return "UNKNOWN_CLOCKID"; -} - /* returns 1 if a <= b, 0 otherwise */ static inline int in_order(struct timespec a, struct timespec b) { @@ -171,15 +142,15 @@ int main(int argc, char *argv[]) for (clockid = userclock; clockid < maxclocks; clockid++) { if (clockid == CLOCK_HWSPECIFIC || clock_gettime(clockid, &ts)) { - ksft_test_result_skip("%-31s\n", clockstring(clockid)); + ksft_test_result_skip("%-31s\n", clock_name(clockid)); continue; } if (consistency_test(clockid, runtime)) { - ksft_test_result_fail("%-31s\n", clockstring(clockid)); + ksft_test_result_fail("%-31s\n", clock_name(clockid)); ksft_exit_fail(); } else { - ksft_test_result_pass("%-31s\n", clockstring(clockid)); + ksft_test_result_pass("%-31s\n", clock_name(clockid)); } } ksft_exit_pass(); diff --git a/tools/testing/selftests/timers/leap-a-day.c b/tools/testing/selftests/timers/leap-a-day.c index 3568cfb3e815..b93cb5714b37 100644 --- a/tools/testing/selftests/timers/leap-a-day.c +++ b/tools/testing/selftests/timers/leap-a-day.c @@ -9,16 +9,19 @@ * kernel's leap-second behavior, as well as how well applications * handle the leap-second discontinuity. * - * Usage: leap-a-day [-s] [-i <num>] + * Usage: leap-a-day [-w] [-i <num>] [-t] * * Options: - * -s: Each iteration, set the date to 10 seconds before midnight GMT. - * This speeds up the number of leapsecond transitions tested, - * but because it calls settimeofday frequently, advancing the - * time by 24 hours every ~16 seconds, it may cause application - * disruption. + * -w: Only set the leap-second flag and wait for the leap second + * each iteration, instead of advancing the time. By default the + * date is set to 10 seconds before midnight GMT, which speeds up + * the number of leapsecond transitions tested, but because it + * calls settimeofday frequently, advancing the time by 24 hours + * every ~16 seconds, it may cause application disruption. * - * -i: Number of iterations to run (default: infinite) + * -i: Number of iterations to run (-1 = infinite, default: 10) + * + * -t: Print TAI time. * * Other notes: Disabling NTP prior to running this is advised, as the two * may conflict in their commands to the kernel. @@ -48,7 +51,7 @@ #include <string.h> #include <signal.h> #include <unistd.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" #define CLOCK_TAI 11 @@ -186,7 +189,7 @@ int main(int argc, char **argv) int opt; /* Process arguments */ - while ((opt = getopt(argc, argv, "sti:")) != -1) { + while ((opt = getopt(argc, argv, "wti:")) != -1) { switch (opt) { case 'w': printf("Only setting leap-flag, not changing time. It could take up to a day for leap to trigger.\n"); diff --git a/tools/testing/selftests/timers/mqueue-lat.c b/tools/testing/selftests/timers/mqueue-lat.c index c0d9368e4fca..fa4c3e3f58fe 100644 --- a/tools/testing/selftests/timers/mqueue-lat.c +++ b/tools/testing/selftests/timers/mqueue-lat.c @@ -29,7 +29,7 @@ #include <signal.h> #include <errno.h> #include <mqueue.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" diff --git a/tools/testing/selftests/timers/nanosleep.c b/tools/testing/selftests/timers/nanosleep.c index a054680b3372..b45e4c855259 100644 --- a/tools/testing/selftests/timers/nanosleep.c +++ b/tools/testing/selftests/timers/nanosleep.c @@ -27,43 +27,9 @@ #include <sys/timex.h> #include <string.h> #include <signal.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" -/* CLOCK_HWSPECIFIC == CLOCK_SGI_CYCLE (Deprecated) */ -#define CLOCK_HWSPECIFIC 10 - -#define UNSUPPORTED 0xf00f - -char *clockstring(int clockid) -{ - switch (clockid) { - case CLOCK_REALTIME: - return "CLOCK_REALTIME"; - case CLOCK_MONOTONIC: - return "CLOCK_MONOTONIC"; - case CLOCK_PROCESS_CPUTIME_ID: - return "CLOCK_PROCESS_CPUTIME_ID"; - case CLOCK_THREAD_CPUTIME_ID: - return "CLOCK_THREAD_CPUTIME_ID"; - case CLOCK_MONOTONIC_RAW: - return "CLOCK_MONOTONIC_RAW"; - case CLOCK_REALTIME_COARSE: - return "CLOCK_REALTIME_COARSE"; - case CLOCK_MONOTONIC_COARSE: - return "CLOCK_MONOTONIC_COARSE"; - case CLOCK_BOOTTIME: - return "CLOCK_BOOTTIME"; - case CLOCK_REALTIME_ALARM: - return "CLOCK_REALTIME_ALARM"; - case CLOCK_BOOTTIME_ALARM: - return "CLOCK_BOOTTIME_ALARM"; - case CLOCK_TAI: - return "CLOCK_TAI"; - }; - return "UNKNOWN_CLOCKID"; -} - /* returns 1 if a <= b, 0 otherwise */ static inline int in_order(struct timespec a, struct timespec b) { @@ -92,15 +58,15 @@ int nanosleep_test(int clockid, long long ns) /* First check abs time */ if (clock_gettime(clockid, &now)) - return UNSUPPORTED; + return KSFT_SKIP; target = timespec_add(now, ns); if (clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL)) - return UNSUPPORTED; + return KSFT_SKIP; clock_gettime(clockid, &now); if (!in_order(target, now)) - return -1; + return KSFT_FAIL; /* Second check reltime */ clock_gettime(clockid, &now); @@ -112,8 +78,8 @@ int nanosleep_test(int clockid, long long ns) clock_gettime(clockid, &now); if (!in_order(target, now)) - return -1; - return 0; + return KSFT_FAIL; + return KSFT_PASS; } static void dummy_event_handler(int val) @@ -132,82 +98,86 @@ static int nanosleep_test_remaining(int clockid) sa.sa_handler = dummy_event_handler; ret = sigaction(SIGALRM, &sa, NULL); if (ret) - return -1; + return KSFT_FAIL; ret = timer_create(clockid, NULL, &timer); if (ret) - return -1; + return KSFT_FAIL; itimer.it_value.tv_nsec = NSEC_PER_SEC / 4; ret = timer_settime(timer, 0, &itimer, NULL); if (ret) - return -1; + return KSFT_FAIL; rqtp.tv_nsec = NSEC_PER_SEC / 2; ret = clock_nanosleep(clockid, 0, &rqtp, &rmtp); - if (ret != EINTR) - return -1; - ret = timer_delete(timer); - if (ret) - return -1; + if (timer_delete(timer)) { + ksft_exit_fail_msg("Unable to delete the timeout timer for %s. " + "This might interfere with following testcases.\n", + clock_name(clockid)); + } + + if (ret != EINTR) + return KSFT_FAIL; sa.sa_handler = SIG_DFL; ret = sigaction(SIGALRM, &sa, NULL); if (ret) - return -1; + return KSFT_FAIL; if (!in_order((struct timespec) {}, rmtp)) - return -1; + return KSFT_FAIL; if (!in_order(rmtp, rqtp)) - return -1; + return KSFT_FAIL; + + return KSFT_PASS; +} - return 0; +static void nanosleep_test_clock(clockid_t clockid) +{ + long long length = 10; + int ret; + + while (length <= (NSEC_PER_SEC * 10)) { + ret = nanosleep_test(clockid, length); + if (ret != KSFT_PASS) { + ksft_test_result_report(ret, "%s\n", clock_name(clockid)); + ksft_test_result_skip("%s (remaining)\n", clock_name(clockid)); + return; + } + + length *= 100; + } + ksft_test_result_pass("%s\n", clock_name(clockid)); + + ret = nanosleep_test_remaining(clockid); + ksft_test_result_report(ret, "%s (remaining)\n", clock_name(clockid)); } int main(int argc, char **argv) { - long long length; - int clockid, ret; - int max_clocks = CLOCK_TAI + 1; + int clockid; - ksft_print_header(); - ksft_set_plan(max_clocks); + static const clockid_t tested_clocks[] = { + CLOCK_REALTIME, + CLOCK_MONOTONIC, + CLOCK_BOOTTIME, + CLOCK_BOOTTIME_ALARM, + CLOCK_REALTIME_ALARM, + CLOCK_TAI, + }; - for (clockid = CLOCK_REALTIME; clockid < max_clocks; clockid++) { + ksft_print_header(); + ksft_set_plan(ARRAY_SIZE(tested_clocks) * 2); - /* Skip cputime clockids since nanosleep won't increment cputime */ - if (clockid == CLOCK_PROCESS_CPUTIME_ID || - clockid == CLOCK_THREAD_CPUTIME_ID || - clockid == CLOCK_HWSPECIFIC) { - ksft_test_result_skip("%-31s\n", clockstring(clockid)); - continue; - } + for (size_t clock_index = 0; clock_index < ARRAY_SIZE(tested_clocks); clock_index++) { + clockid = tested_clocks[clock_index]; fflush(stdout); - length = 10; - while (length <= (NSEC_PER_SEC * 10)) { - ret = nanosleep_test(clockid, length); - if (ret == UNSUPPORTED) { - ksft_test_result_skip("%-31s\n", clockstring(clockid)); - goto next; - } - if (ret < 0) { - ksft_test_result_fail("%-31s\n", clockstring(clockid)); - ksft_exit_fail(); - } - length *= 100; - } - ret = nanosleep_test_remaining(clockid); - if (ret < 0) { - ksft_test_result_fail("%-31s\n", clockstring(clockid)); - ksft_exit_fail(); - } - ksft_test_result_pass("%-31s\n", clockstring(clockid)); -next: - ret = 0; + nanosleep_test_clock(clockid); } - ksft_exit_pass(); + ksft_finished(); } diff --git a/tools/testing/selftests/timers/nsleep-lat.c b/tools/testing/selftests/timers/nsleep-lat.c index a7ba1eb1e21b..5de0051ac8e3 100644 --- a/tools/testing/selftests/timers/nsleep-lat.c +++ b/tools/testing/selftests/timers/nsleep-lat.c @@ -24,44 +24,10 @@ #include <sys/timex.h> #include <string.h> #include <signal.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" -#define UNRESONABLE_LATENCY 40000000 /* 40ms in nanosecs */ - -/* CLOCK_HWSPECIFIC == CLOCK_SGI_CYCLE (Deprecated) */ -#define CLOCK_HWSPECIFIC 10 - -#define UNSUPPORTED 0xf00f - -char *clockstring(int clockid) -{ - switch (clockid) { - case CLOCK_REALTIME: - return "CLOCK_REALTIME"; - case CLOCK_MONOTONIC: - return "CLOCK_MONOTONIC"; - case CLOCK_PROCESS_CPUTIME_ID: - return "CLOCK_PROCESS_CPUTIME_ID"; - case CLOCK_THREAD_CPUTIME_ID: - return "CLOCK_THREAD_CPUTIME_ID"; - case CLOCK_MONOTONIC_RAW: - return "CLOCK_MONOTONIC_RAW"; - case CLOCK_REALTIME_COARSE: - return "CLOCK_REALTIME_COARSE"; - case CLOCK_MONOTONIC_COARSE: - return "CLOCK_MONOTONIC_COARSE"; - case CLOCK_BOOTTIME: - return "CLOCK_BOOTTIME"; - case CLOCK_REALTIME_ALARM: - return "CLOCK_REALTIME_ALARM"; - case CLOCK_BOOTTIME_ALARM: - return "CLOCK_BOOTTIME_ALARM"; - case CLOCK_TAI: - return "CLOCK_TAI"; - }; - return "UNKNOWN_CLOCKID"; -} +#define UNRESONABLE_LATENCY (40 * NSEC_PER_MSEC) struct timespec timespec_add(struct timespec ts, unsigned long long ns) { @@ -92,58 +58,68 @@ int nanosleep_lat_test(int clockid, long long ns) target.tv_nsec = ns%NSEC_PER_SEC; if (clock_gettime(clockid, &start)) - return UNSUPPORTED; + return KSFT_SKIP; if (clock_nanosleep(clockid, 0, &target, NULL)) - return UNSUPPORTED; + return KSFT_SKIP; count = 10; /* First check relative latency */ - clock_gettime(clockid, &start); - for (i = 0; i < count; i++) - clock_nanosleep(clockid, 0, &target, NULL); - clock_gettime(clockid, &end); + if (clock_gettime(clockid, &start)) + return KSFT_FAIL; + + for (i = 0; i < count; i++) { + if (clock_nanosleep(clockid, 0, &target, NULL)) + return KSFT_FAIL; + } + + if (clock_gettime(clockid, &end)) + return KSFT_FAIL; if (((timespec_sub(start, end)/count)-ns) > UNRESONABLE_LATENCY) { ksft_print_msg("Large rel latency: %lld ns :", (timespec_sub(start, end)/count)-ns); - return -1; + return KSFT_FAIL; } /* Next check absolute latency */ for (i = 0; i < count; i++) { - clock_gettime(clockid, &start); + if (clock_gettime(clockid, &start)) + return KSFT_FAIL; target = timespec_add(start, ns); - clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL); - clock_gettime(clockid, &end); + if (clock_nanosleep(clockid, TIMER_ABSTIME, &target, NULL)) + return KSFT_FAIL; + if (clock_gettime(clockid, &end)) + return KSFT_FAIL; latency += timespec_sub(target, end); } if (latency/count > UNRESONABLE_LATENCY) { ksft_print_msg("Large abs latency: %lld ns :", latency/count); - return -1; + return KSFT_FAIL; } - return 0; + return KSFT_PASS; } -#define SKIPPED_CLOCK_COUNT 3 - int main(int argc, char **argv) { long long length; int clockid, ret; - int max_clocks = CLOCK_TAI + 1; - ksft_print_header(); - ksft_set_plan(max_clocks - CLOCK_REALTIME - SKIPPED_CLOCK_COUNT); + static const clockid_t tested_clocks[] = { + CLOCK_REALTIME, + CLOCK_MONOTONIC, + CLOCK_BOOTTIME, + CLOCK_BOOTTIME_ALARM, + CLOCK_REALTIME_ALARM, + CLOCK_TAI, + }; - for (clockid = CLOCK_REALTIME; clockid < max_clocks; clockid++) { + ksft_print_header(); + ksft_set_plan(ARRAY_SIZE(tested_clocks)); - /* Skip cputime clockids since nanosleep won't increment cputime */ - if (clockid == CLOCK_PROCESS_CPUTIME_ID || - clockid == CLOCK_THREAD_CPUTIME_ID || - clockid == CLOCK_HWSPECIFIC) - continue; + for (size_t clock_index = 0; clock_index < ARRAY_SIZE(tested_clocks); clock_index++) { + clockid = tested_clocks[clock_index]; length = 10; while (length <= (NSEC_PER_SEC * 10)) { @@ -154,12 +130,7 @@ int main(int argc, char **argv) } - if (ret == UNSUPPORTED) { - ksft_test_result_skip("%s\n", clockstring(clockid)); - } else { - ksft_test_result(ret >= 0, "%s\n", - clockstring(clockid)); - } + ksft_test_result_report(ret, "%s\n", clock_name(clockid)); } ksft_finished(); diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index 2f3bac9fc6e8..a92d4b957747 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c @@ -16,10 +16,10 @@ #include <string.h> #include <unistd.h> #include <time.h> -#include <include/vdso/time64.h> #include <pthread.h> #include <stdbool.h> +#include "clock-helpers.h" #include "kselftest.h" #define DELAY 2 @@ -141,8 +141,9 @@ static void check_itimer(int which, const char *name) ksft_test_result(check_diff(start, end) == 0, "%s\n", name); } -static void check_timer_create(int which, const char *name) +static void check_timer_create(int which) { + const char *name = clock_name(which); struct timespec start, end; struct itimerspec val = { .it_value.tv_sec = DELAY, @@ -455,8 +456,9 @@ static void check_delete(void) ksft_test_result(!tsig.signals, "check_delete\n"); } -static void check_sigev_none(int which, const char *name) +static void check_sigev_none(int which) { + const char *name = clock_name(which); struct timespec start, now; struct itimerspec its; struct sigevent sev; @@ -493,8 +495,9 @@ static void check_sigev_none(int which, const char *name) "check_sigev_none %s\n", name); } -static void check_gettime(int which, const char *name) +static void check_gettime(int which) { + const char *name = clock_name(which); struct itimerspec its, prev; struct timespec start, now; struct sigevent sev; @@ -546,8 +549,9 @@ static void check_gettime(int which, const char *name) ksft_test_result(wraps > 1, "check_gettime %s\n", name); } -static void check_overrun(int which, const char *name) +static void check_overrun(int which) { + const char *name = clock_name(which); struct timespec start, now; struct tmrsig tsig = { }; struct itimerspec its; @@ -689,7 +693,7 @@ int main(int argc, char **argv) check_itimer(ITIMER_VIRTUAL, "ITIMER_VIRTUAL"); check_itimer(ITIMER_PROF, "ITIMER_PROF"); check_itimer(ITIMER_REAL, "ITIMER_REAL"); - check_timer_create(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID"); + check_timer_create(CLOCK_THREAD_CPUTIME_ID); /* * It's unfortunately hard to reliably test a timer expiration @@ -700,7 +704,7 @@ int main(int argc, char **argv) * to ensure true parallelism. So test only one thread until we * find a better solution. */ - check_timer_create(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID"); + check_timer_create(CLOCK_PROCESS_CPUTIME_ID); check_timer_distribution(); if (run_sig_ign_tests) { @@ -708,18 +712,18 @@ int main(int argc, char **argv) check_sig_ign(1); check_rearm(); check_delete(); - check_sigev_none(CLOCK_MONOTONIC, "CLOCK_MONOTONIC"); - check_sigev_none(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID"); - check_gettime(CLOCK_MONOTONIC, "CLOCK_MONOTONIC"); - check_gettime(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID"); - check_gettime(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID"); + check_sigev_none(CLOCK_MONOTONIC); + check_sigev_none(CLOCK_PROCESS_CPUTIME_ID); + check_gettime(CLOCK_MONOTONIC); + check_gettime(CLOCK_PROCESS_CPUTIME_ID); + check_gettime(CLOCK_THREAD_CPUTIME_ID); } else { ksft_print_msg("Skipping SIG_IGN tests on kernel < 6.13\n"); } - check_overrun(CLOCK_MONOTONIC, "CLOCK_MONOTONIC"); - check_overrun(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID"); - check_overrun(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID"); + check_overrun(CLOCK_MONOTONIC); + check_overrun(CLOCK_PROCESS_CPUTIME_ID); + check_overrun(CLOCK_THREAD_CPUTIME_ID); ksft_finished(); } diff --git a/tools/testing/selftests/timers/raw_skew.c b/tools/testing/selftests/timers/raw_skew.c index a7bae7d80916..0c87a8fb0d7f 100644 --- a/tools/testing/selftests/timers/raw_skew.c +++ b/tools/testing/selftests/timers/raw_skew.c @@ -25,7 +25,7 @@ #include <sys/time.h> #include <sys/timex.h> #include <time.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" #define shift_right(x, s) ({ \ diff --git a/tools/testing/selftests/timers/set-2038.c b/tools/testing/selftests/timers/set-2038.c index ecc171de4728..f522a3035ec6 100644 --- a/tools/testing/selftests/timers/set-2038.c +++ b/tools/testing/selftests/timers/set-2038.c @@ -27,7 +27,7 @@ #include <unistd.h> #include <time.h> #include <sys/time.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" #define KTIME_MAX ((long long)~((unsigned long long)1 << 63)) diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c index 44d2e3614fa5..79ddba25d314 100644 --- a/tools/testing/selftests/timers/set-timer-lat.c +++ b/tools/testing/selftests/timers/set-timer-lat.c @@ -28,7 +28,7 @@ #include <signal.h> #include <stdlib.h> #include <pthread.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" /* CLOCK_HWSPECIFIC == CLOCK_SGI_CYCLE (Deprecated) */ @@ -43,36 +43,6 @@ struct timespec start_time; long long max_latency_ns; int timer_fired_early; -char *clockstring(int clockid) -{ - switch (clockid) { - case CLOCK_REALTIME: - return "CLOCK_REALTIME"; - case CLOCK_MONOTONIC: - return "CLOCK_MONOTONIC"; - case CLOCK_PROCESS_CPUTIME_ID: - return "CLOCK_PROCESS_CPUTIME_ID"; - case CLOCK_THREAD_CPUTIME_ID: - return "CLOCK_THREAD_CPUTIME_ID"; - case CLOCK_MONOTONIC_RAW: - return "CLOCK_MONOTONIC_RAW"; - case CLOCK_REALTIME_COARSE: - return "CLOCK_REALTIME_COARSE"; - case CLOCK_MONOTONIC_COARSE: - return "CLOCK_MONOTONIC_COARSE"; - case CLOCK_BOOTTIME: - return "CLOCK_BOOTTIME"; - case CLOCK_REALTIME_ALARM: - return "CLOCK_REALTIME_ALARM"; - case CLOCK_BOOTTIME_ALARM: - return "CLOCK_BOOTTIME_ALARM"; - case CLOCK_TAI: - return "CLOCK_TAI"; - } - return "UNKNOWN_CLOCKID"; -} - - long long timespec_sub(struct timespec a, struct timespec b) { long long ret = NSEC_PER_SEC * b.tv_sec + b.tv_nsec; @@ -103,7 +73,7 @@ void sigalarm(int signo) void describe_timer(int flags, int interval) { printf("%-22s %s %s ", - clockstring(clock_id), + clock_name(clock_id), flags ? "ABSTIME":"RELTIME", interval ? "PERIODIC":"ONE-SHOT"); } @@ -129,12 +99,12 @@ int setup_timer(int clock_id, int flags, int interval, timer_t *tm1) if ((clock_id == CLOCK_REALTIME_ALARM) || (clock_id == CLOCK_BOOTTIME_ALARM)) { printf("%-22s %s missing CAP_WAKE_ALARM? : [UNSUPPORTED]\n", - clockstring(clock_id), + clock_name(clock_id), flags ? "ABSTIME":"RELTIME"); /* Indicate timer isn't set, so caller doesn't wait */ return 1; } - printf("%s - timer_create() failed\n", clockstring(clock_id)); + printf("%s - timer_create() failed\n", clock_name(clock_id)); return -1; } @@ -151,7 +121,7 @@ int setup_timer(int clock_id, int flags, int interval, timer_t *tm1) err = timer_settime(*tm1, flags, &its1, &its2); if (err) { - printf("%s - timer_settime() failed\n", clockstring(clock_id)); + printf("%s - timer_settime() failed\n", clock_name(clock_id)); return -1; } diff --git a/tools/testing/selftests/timers/valid-adjtimex.c b/tools/testing/selftests/timers/valid-adjtimex.c index e1e56d3097d6..f641d5fb0902 100644 --- a/tools/testing/selftests/timers/valid-adjtimex.c +++ b/tools/testing/selftests/timers/valid-adjtimex.c @@ -29,7 +29,7 @@ #include <string.h> #include <signal.h> #include <unistd.h> -#include <include/vdso/time64.h> +#include "clock-helpers.h" #include "kselftest.h" #define ADJ_SETOFFSET 0x0100 |
