Skip to content

Commit 8e63360

Browse files
committed
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 <[email protected]> Reviewed-by: Frederic Weisbecker <[email protected]> Link: https://lore.kernel.org/all/8734fl2tkx.ffs@tglx
1 parent ec2d0c0 commit 8e63360

File tree

1 file changed

+72
-1
lines changed

1 file changed

+72
-1
lines changed

tools/testing/selftests/timers/posix_timers.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Kernel loop code stolen from Steven Rostedt <[email protected]>
88
*/
99
#define _GNU_SOURCE
10+
#include <sys/prctl.h>
1011
#include <sys/time.h>
1112
#include <sys/types.h>
1213
#include <stdio.h>
@@ -599,14 +600,84 @@ static void check_overrun(int which, const char *name)
599600
"check_overrun %s\n", name);
600601
}
601602

603+
#include <sys/syscall.h>
604+
605+
static int do_timer_create(int *id)
606+
{
607+
return syscall(__NR_timer_create, CLOCK_MONOTONIC, NULL, id);
608+
}
609+
610+
static int do_timer_delete(int id)
611+
{
612+
return syscall(__NR_timer_delete, id);
613+
}
614+
615+
#ifndef PR_TIMER_CREATE_RESTORE_IDS
616+
# define PR_TIMER_CREATE_RESTORE_IDS 77
617+
# define PR_TIMER_CREATE_RESTORE_IDS_OFF 0
618+
# define PR_TIMER_CREATE_RESTORE_IDS_ON 1
619+
# define PR_TIMER_CREATE_RESTORE_IDS_GET 2
620+
#endif
621+
622+
static void check_timer_create_exact(void)
623+
{
624+
int id;
625+
626+
if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_ON, 0, 0, 0)) {
627+
switch (errno) {
628+
case EINVAL:
629+
ksft_test_result_skip("check timer create exact, not supported\n");
630+
return;
631+
default:
632+
ksft_test_result_skip("check timer create exact, errno = %d\n", errno);
633+
return;
634+
}
635+
}
636+
637+
if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_GET, 0, 0, 0) != 1)
638+
fatal_error(NULL, "prctl(GET) failed\n");
639+
640+
id = 8;
641+
if (do_timer_create(&id) < 0)
642+
fatal_error(NULL, "timer_create()");
643+
644+
if (do_timer_delete(id))
645+
fatal_error(NULL, "timer_delete()");
646+
647+
if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_OFF, 0, 0, 0))
648+
fatal_error(NULL, "prctl(OFF)");
649+
650+
if (prctl(PR_TIMER_CREATE_RESTORE_IDS, PR_TIMER_CREATE_RESTORE_IDS_GET, 0, 0, 0) != 0)
651+
fatal_error(NULL, "prctl(GET) failed\n");
652+
653+
if (id != 8) {
654+
ksft_test_result_fail("check timer create exact %d != 8\n", id);
655+
return;
656+
}
657+
658+
/* Validate that it went back to normal mode and allocates ID 9 */
659+
if (do_timer_create(&id) < 0)
660+
fatal_error(NULL, "timer_create()");
661+
662+
if (do_timer_delete(id))
663+
fatal_error(NULL, "timer_delete()");
664+
665+
if (id == 9)
666+
ksft_test_result_pass("check timer create exact\n");
667+
else
668+
ksft_test_result_fail("check timer create exact. Disabling failed.\n");
669+
}
670+
602671
int main(int argc, char **argv)
603672
{
604673
ksft_print_header();
605-
ksft_set_plan(18);
674+
ksft_set_plan(19);
606675

607676
ksft_print_msg("Testing posix timers. False negative may happen on CPU execution \n");
608677
ksft_print_msg("based timers if other threads run on the CPU...\n");
609678

679+
check_timer_create_exact();
680+
610681
check_itimer(ITIMER_VIRTUAL, "ITIMER_VIRTUAL");
611682
check_itimer(ITIMER_PROF, "ITIMER_PROF");
612683
check_itimer(ITIMER_REAL, "ITIMER_REAL");

0 commit comments

Comments
 (0)