From 45aeb7b3039355cfaf01ee1f7e104a55a8d61d0b Mon Sep 17 00:00:00 2001 From: Hung-Jui Lin Date: Fri, 23 Oct 2026 23:14:11 +0800 Subject: [PATCH] selftests: timers: Add a test for disarmed SIGEV_NONE timers timer_gettime() must report a zero it_value for a disarmed timer. For SIGEV_NONE timers, common_timer_get() reported the remaining time of the previous arming instead. Add check_sigev_none_disarm(). It arms a SIGEV_NONE oneshot timer, checks that a remaining time is reported, disarms the timer and checks that it_value is zero. Run it for CLOCK_MONOTONIC and CLOCK_PROCESS_CPUTIME_ID, as CPU timers use a separate implementation. Without the preceding fix, the CLOCK_MONOTONIC case fails. Signed-off-by: Hung-Jui Lin Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20261023151411.28685-2-alex.lin.programmer@gmail.com --- tools/testing/selftests/timers/posix_timers.c | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c index a92d4b957747..1cf644402b96 100644 --- a/tools/testing/selftests/timers/posix_timers.c +++ b/tools/testing/selftests/timers/posix_timers.c @@ -495,6 +495,45 @@ static void check_sigev_none(int which) "check_sigev_none %s\n", name); } +static void check_sigev_none_disarm(int which) +{ + const char *name = clock_name(which); + struct itimerspec its; + struct sigevent sev; + timer_t timerid; + bool armed; + + memset(&sev, 0, sizeof(sev)); + sev.sigev_notify = SIGEV_NONE; + + if (timer_create(which, &sev, &timerid)) + fatal_error(name, "timer_create()"); + + /* Start a oneshot timer which does not expire during the test */ + memset(&its, 0, sizeof(its)); + its.it_value.tv_sec = 100; + if (timer_settime(timerid, 0, &its, NULL)) + fatal_error(name, "timer_settime()"); + + if (timer_gettime(timerid, &its)) + fatal_error(name, "timer_gettime()"); + armed = its.it_value.tv_sec || its.it_value.tv_nsec; + + /* Disarm it. The remaining time must be reported as 0 */ + memset(&its, 0, sizeof(its)); + if (timer_settime(timerid, 0, &its, NULL)) + fatal_error(name, "timer_settime()"); + + if (timer_gettime(timerid, &its)) + fatal_error(name, "timer_gettime()"); + + if (timer_delete(timerid)) + fatal_error(name, "timer_delete()"); + + ksft_test_result(armed && !its.it_value.tv_sec && !its.it_value.tv_nsec, + "%s %s\n", __func__, name); +} + static void check_gettime(int which) { const char *name = clock_name(which); @@ -680,7 +719,7 @@ int main(int argc, char **argv) ksft_print_header(); if (run_sig_ign_tests) { - ksft_set_plan(19); + ksft_set_plan(21); } else { ksft_set_plan(10); } @@ -714,6 +753,8 @@ int main(int argc, char **argv) check_delete(); check_sigev_none(CLOCK_MONOTONIC); check_sigev_none(CLOCK_PROCESS_CPUTIME_ID); + check_sigev_none_disarm(CLOCK_MONOTONIC); + check_sigev_none_disarm(CLOCK_PROCESS_CPUTIME_ID); check_gettime(CLOCK_MONOTONIC); check_gettime(CLOCK_PROCESS_CPUTIME_ID); check_gettime(CLOCK_THREAD_CPUTIME_ID);