xref: /linux/kernel/trace/rv/monitors/sleep/sleep_kunit.c (revision 55ee4b931a7ffedc886175d265dd6e6d08fd4151)
1*51f3fe70SGabriele Monaco // SPDX-License-Identifier: GPL-2.0
2*51f3fe70SGabriele Monaco #include <linux/kernel.h>
3*51f3fe70SGabriele Monaco #include <linux/rv.h>
4*51f3fe70SGabriele Monaco #include <rv/kunit.h>
5*51f3fe70SGabriele Monaco #include <trace/events/syscalls.h>
6*51f3fe70SGabriele Monaco #include <trace/events/sched.h>
7*51f3fe70SGabriele Monaco #include <uapi/linux/futex.h>
8*51f3fe70SGabriele Monaco #include "sleep_kunit.h"
9*51f3fe70SGabriele Monaco 
10*51f3fe70SGabriele Monaco #if IS_REACHABLE(CONFIG_RV_MON_SLEEP)
11*51f3fe70SGabriele Monaco 
12*51f3fe70SGabriele Monaco static void rv_test_sleep(struct kunit *test)
13*51f3fe70SGabriele Monaco {
14*51f3fe70SGabriele Monaco 	struct task_struct *target = rv_kunit_alloc_mock_task(test);
15*51f3fe70SGabriele Monaco 	struct task_struct *other = rv_kunit_alloc_mock_task(test);
16*51f3fe70SGabriele Monaco 	struct rv_kunit_ctx *ctx = test->priv;
17*51f3fe70SGabriele Monaco 	unsigned long args[6] = {0};
18*51f3fe70SGabriele Monaco 	struct pt_regs regs = {0};
19*51f3fe70SGabriele Monaco 
20*51f3fe70SGabriele Monaco 	prepare_test(test, &rv_sleep_ops.mon);
21*51f3fe70SGabriele Monaco 	target->policy = SCHED_FIFO;
22*51f3fe70SGabriele Monaco 	target->prio = MAX_RT_PRIO - 2;
23*51f3fe70SGabriele Monaco 	other->policy = SCHED_FIFO;
24*51f3fe70SGabriele Monaco 	other->prio = MAX_RT_PRIO - 1;
25*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_task_newtask(NULL, target, 0);
26*51f3fe70SGabriele Monaco 
27*51f3fe70SGabriele Monaco 	/* RT task sleeps on a non RT-friendly nanosleep */
28*51f3fe70SGabriele Monaco 	rv_mock_current(target);
29*51f3fe70SGabriele Monaco 	args[0] = CLOCK_REALTIME;
30*51f3fe70SGabriele Monaco 	syscall_set_arguments(target, &regs, args);
31*51f3fe70SGabriele Monaco #ifdef __NR_clock_nanosleep
32*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_sys_enter(NULL, &regs, __NR_clock_nanosleep);
33*51f3fe70SGabriele Monaco #elif defined(__NR_clock_nanosleep_time64)
34*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_sys_enter(NULL, &regs, __NR_clock_nanosleep_time64);
35*51f3fe70SGabriele Monaco #endif
36*51f3fe70SGabriele Monaco 	RV_KUNIT_EXPECT_REACTION_HERE(test, ctx)
37*51f3fe70SGabriele Monaco 		rv_sleep_ops.handle_sched_set_state(NULL, target, TASK_INTERRUPTIBLE);
38*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_sys_exit(NULL, NULL, 0);
39*51f3fe70SGabriele Monaco 
40*51f3fe70SGabriele Monaco 	/* RT task woken up by lower priority task */
41*51f3fe70SGabriele Monaco 	args[1] = FUTEX_WAIT;
42*51f3fe70SGabriele Monaco 	syscall_set_arguments(target, &regs, args);
43*51f3fe70SGabriele Monaco 	rv_mock_current(target);
44*51f3fe70SGabriele Monaco #ifdef __NR_futex
45*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_sys_enter(NULL, &regs, __NR_futex);
46*51f3fe70SGabriele Monaco #elif defined(__NR_futex_time64)
47*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_sys_enter(NULL, &regs, __NR_futex_time64);
48*51f3fe70SGabriele Monaco #endif
49*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_sched_set_state(NULL, target, TASK_INTERRUPTIBLE);
50*51f3fe70SGabriele Monaco 	rv_mock_current(other);
51*51f3fe70SGabriele Monaco 	rv_sleep_ops.handle_sched_waking(NULL, target);
52*51f3fe70SGabriele Monaco 	rv_mock_current(target);
53*51f3fe70SGabriele Monaco 	RV_KUNIT_EXPECT_REACTION_HERE(test, ctx)
54*51f3fe70SGabriele Monaco 		rv_sleep_ops.handle_sched_exit(NULL, true);
55*51f3fe70SGabriele Monaco }
56*51f3fe70SGabriele Monaco 
57*51f3fe70SGabriele Monaco #else
58*51f3fe70SGabriele Monaco #define rv_test_sleep rv_test_stub
59*51f3fe70SGabriele Monaco #endif
60