[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250224101343.672288753@linutronix.de>
Date: Mon, 24 Feb 2025 11:15:41 +0100 (CET)
From: Thomas Gleixner <tglx@...utronix.de>
To: LKML <linux-kernel@...r.kernel.org>
Cc: Anna-Maria Behnsen <anna-maria@...utronix.de>,
Frederic Weisbecker <frederic@...nel.org>,
Benjamin Segall <bsegall@...gle.com>,
Eric Dumazet <edumazet@...gle.com>,
Andrey Vagin <avagin@...nvz.org>,
Pavel Tikhomirov <ptikhomirov@...tuozzo.com>,
Peter Zijlstra <peterz@...radead.org>
Subject: [patch 11/11] selftests/timers/posix-timers: Add a test for exact
allocation mode
The exact timer ID allocation mode is used by CRIU to restore timers with a
given ID. Add a test case for it.
It's skipped on older kernels when the prctl() fails.
Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
---
tools/testing/selftests/timers/posix_timers.c | 68 +++++++++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
--- a/tools/testing/selftests/timers/posix_timers.c
+++ b/tools/testing/selftests/timers/posix_timers.c
@@ -7,6 +7,7 @@
* Kernel loop code stolen from Steven Rostedt <srostedt@...hat.com>
*/
#define _GNU_SOURCE
+#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdio.h>
@@ -599,14 +600,79 @@ static void check_overrun(int which, con
"check_overrun %s\n", name);
}
+#include <sys/syscall.h>
+
+static int do_timer_create(int *id)
+{
+ return syscall(__NR_timer_create, CLOCK_MONOTONIC, NULL, id);
+}
+
+static int do_timer_delete(int id)
+{
+ return syscall(__NR_timer_delete, id);
+}
+
+static void check_timer_create_exact(void)
+{
+ int id, rid;
+
+ /* Allocate a timer for comparison after switch back from exact mode */
+ if (do_timer_create(&id) < 0)
+ fatal_error(NULL, "timer_create()");
+
+ if (do_timer_delete(id))
+ fatal_error(NULL, "timer_delete()");
+
+ if (prctl(77, 1, 0, 0, 0)) {
+ switch (errno) {
+ case EINVAL:
+ ksft_test_result_skip("check timer create exact, not supported\n");
+ return;
+ default:
+ ksft_test_result_skip("check timer create exact, errno = %d\n", errno);
+ return;
+ }
+ }
+
+ rid = id + 8;
+ if (do_timer_create(&rid) < 0)
+ fatal_error(NULL, "timer_create()");
+
+ if (do_timer_delete(rid))
+ fatal_error(NULL, "timer_delete()");
+
+ if (prctl(77, 0, 0, 0, 0))
+ fatal_error(NULL, "prctl()");
+
+ if (rid != id + 8) {
+ ksft_test_result_fail("check timer create exact %d != %d\n", rid, id + 8);
+ return;
+ }
+
+ /* Validate that it went back to normal mode */
+ if (do_timer_create(&rid) < 0)
+ fatal_error(NULL, "timer_create()");
+
+ if (do_timer_delete(rid))
+ fatal_error(NULL, "timer_delete()");
+
+ /* Same ID if linear mode is off, next ID if enabled */
+ if (rid == id || rid == id + 1)
+ ksft_test_result_pass("check timer create exact\n");
+ else
+ ksft_test_result_fail("check timer create exact. Disabling failed.\n");
+}
+
int main(int argc, char **argv)
{
ksft_print_header();
- ksft_set_plan(18);
+ ksft_set_plan(19);
ksft_print_msg("Testing posix timers. False negative may happen on CPU execution \n");
ksft_print_msg("based timers if other threads run on the CPU...\n");
+ check_timer_create_exact();
+
check_itimer(ITIMER_VIRTUAL, "ITIMER_VIRTUAL");
check_itimer(ITIMER_PROF, "ITIMER_PROF");
check_itimer(ITIMER_REAL, "ITIMER_REAL");
Powered by blists - more mailing lists