xref: /aosp_15_r20/external/ltp/testcases/kernel/sched/sysctl/proc_sched_rt01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2023 Cyril Hrubis <[email protected]>
4  */
5 
6 /*\
7  * [Description]
8  *
9  * Sanity tests for the /proc/sys/kernel/sched_r* files.
10  *
11  * - The sched_rt_period_us range is 1 to INT_MAX
12  *   try invalid values and check for EINVAL
13  *
14  * - The sched_rt_runtime_us range is -1 to INT_MAX
15  *   try invalid values and check for EINVAL
16  *
17  * - The sched_rt_runtime_us must be less or equal to sched_rt_period_us
18  *
19  * - Reset sched_rr_timeslice_ms to default value by writing -1 and check that
20  *   we get the default value on next read.
21  *
22  * This is a regression test for a commits:
23  *
24  *  - c1fc6484e1fb ("sched/rt: sysctl_sched_rr_timeslice show default timeslice after reset")
25  *  - 079be8fc6309 ("sched/rt: Disallow writing invalid values to sched_rt_period_us")
26  */
27 
28 #include <stdio.h>
29 #include "tst_test.h"
30 
31 #define RT_PERIOD_US "/proc/sys/kernel/sched_rt_period_us"
32 #define RT_RUNTIME_US "/proc/sys/kernel/sched_rt_runtime_us"
33 #define RR_TIMESLICE_MS "/proc/sys/kernel/sched_rr_timeslice_ms"
34 
35 static int period_fd;
36 static int runtime_fd;
37 
rr_timeslice_ms_reset(void)38 static void rr_timeslice_ms_reset(void)
39 {
40 	long timeslice_ms;
41 
42 	SAFE_FILE_PRINTF(RR_TIMESLICE_MS, "-1");
43 	SAFE_FILE_SCANF(RR_TIMESLICE_MS, "%li", &timeslice_ms);
44 
45 	TST_EXP_EXPR(timeslice_ms > 0,
46 		"timeslice_ms > 0 after reset to default");
47 }
48 
rt_period_us_einval(void)49 static void rt_period_us_einval(void)
50 {
51 	TST_EXP_FAIL(write(period_fd, "0", 2), EINVAL,
52 		"echo 0 > "RT_PERIOD_US);
53 	TST_EXP_FAIL(write(period_fd, "-1", 2), EINVAL,
54 		"echo -1 > "RT_PERIOD_US);
55 }
56 
rt_runtime_us_einval(void)57 static void rt_runtime_us_einval(void)
58 {
59 	TST_EXP_FAIL(write(runtime_fd, "-2", 2), EINVAL,
60 		"echo -2 > "RT_RUNTIME_US);
61 }
62 
rt_runtime_us_le_period_us(void)63 static void rt_runtime_us_le_period_us(void)
64 {
65 	int period_us;
66 	char buf[32];
67 
68 	SAFE_FILE_SCANF(RT_PERIOD_US, "%i", &period_us);
69 
70 	sprintf(buf, "%i", period_us+1);
71 
72 	TST_EXP_FAIL(write(runtime_fd, buf, strlen(buf)), EINVAL,
73 		"echo rt_period_us+1 > "RT_RUNTIME_US);
74 }
75 
verify_sched_proc(void)76 static void verify_sched_proc(void)
77 {
78 	rr_timeslice_ms_reset();
79 	rt_period_us_einval();
80 	rt_runtime_us_einval();
81 	rt_runtime_us_le_period_us();
82 }
83 
setup(void)84 static void setup(void)
85 {
86 	period_fd = open(RT_PERIOD_US, O_RDWR);
87 	runtime_fd = open(RT_RUNTIME_US, O_RDWR);
88 }
89 
cleanup(void)90 static void cleanup(void)
91 {
92 	if (period_fd > 0)
93 		SAFE_CLOSE(period_fd);
94 
95 	if (runtime_fd > 0)
96 		SAFE_CLOSE(runtime_fd);
97 }
98 
99 static struct tst_test test = {
100 	.needs_root = 1,
101 	.setup = setup,
102 	.cleanup = cleanup,
103 	.test_all = verify_sched_proc,
104 	.tags = (struct tst_tag []) {
105 		{"linux-git", "c1fc6484e1fb"},
106 		{"linux-git", "079be8fc6309"},
107 		{}
108 	},
109 	.needs_kconfigs = (const char *[]) {
110 		"CONFIG_SYSCTL",
111 		NULL
112 	},
113 };
114