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