Skip to content

Commit 0b82cc3

Browse files
theihorhtejun
authored andcommitted
selftests/sched_ext: Fix rt_stall flaky failure
The rt_stall test measures the runtime ratio between an EXT and an RT task pinned to the same CPU, verifying that the deadline server prevents RT tasks from starving SCHED_EXT tasks. It expects the EXT task to get at least 4% of CPU time. The test is flaky because sched_stress_test() calls sleep(RUN_TIME) immediately after fork(), without waiting for the RT child to complete its setup (set_affinity + set_sched). If the RT child experiences scheduling latency before completing setup, that delay eats into the measurement window: the RT child runs for less than RUN_TIME seconds, and the EXT task's measured ratio drops below the 4% threshold. For example, in the failing CI run [1]: EXT=0.140s RT=4.750s total=4.890s (expected ~5.0s) ratio=2.86% < 4% → FAIL The 110ms gap (5.0 - 4.89) corresponds to the RT child's setup time being counted inside the measurement window, during which fewer deadline server ticks fire for the EXT task. Fix by using pipes to synchronize: each child signals the parent after completing its setup, and the parent waits for both signals before starting sleep(RUN_TIME). This ensures the measurement window only counts time when both tasks are fully configured and competing. [1] https://github.com/kernel-patches/bpf/actions/runs/21961895809/job/63442490449 Fixes: be621a7 ("selftests/sched_ext: Add test for sched_ext dl_server") Assisted-by: claude-opus-4-6-v1 Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev> Reviewed-by: Andrea Righi <arighi@nvidia.com> Signed-off-by: Tejun Heo <tj@kernel.org>
1 parent 048714d commit 0b82cc3

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

tools/testing/selftests/sched_ext/rt_stall.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,30 @@
2323
#define CORE_ID 0 /* CPU to pin tasks to */
2424
#define RUN_TIME 5 /* How long to run the test in seconds */
2525

26+
/* Signal the parent that setup is complete by writing to a pipe */
27+
static void signal_ready(int fd)
28+
{
29+
char c = 1;
30+
31+
if (write(fd, &c, 1) != 1) {
32+
perror("write to ready pipe");
33+
exit(EXIT_FAILURE);
34+
}
35+
close(fd);
36+
}
37+
38+
/* Wait for a child to signal readiness via a pipe */
39+
static void wait_ready(int fd)
40+
{
41+
char c;
42+
43+
if (read(fd, &c, 1) != 1) {
44+
perror("read from ready pipe");
45+
exit(EXIT_FAILURE);
46+
}
47+
close(fd);
48+
}
49+
2650
/* Simple busy-wait function for test tasks */
2751
static void process_func(void)
2852
{
@@ -122,14 +146,24 @@ static bool sched_stress_test(bool is_ext)
122146

123147
float ext_runtime, rt_runtime, actual_ratio;
124148
int ext_pid, rt_pid;
149+
int ext_ready[2], rt_ready[2];
125150

126151
ksft_print_header();
127152
ksft_set_plan(1);
128153

154+
if (pipe(ext_ready) || pipe(rt_ready)) {
155+
perror("pipe");
156+
ksft_exit_fail();
157+
}
158+
129159
/* Create and set up a EXT task */
130160
ext_pid = fork();
131161
if (ext_pid == 0) {
162+
close(ext_ready[0]);
163+
close(rt_ready[0]);
164+
close(rt_ready[1]);
132165
set_affinity(CORE_ID);
166+
signal_ready(ext_ready[1]);
133167
process_func();
134168
exit(0);
135169
} else if (ext_pid < 0) {
@@ -140,15 +174,30 @@ static bool sched_stress_test(bool is_ext)
140174
/* Create an RT task */
141175
rt_pid = fork();
142176
if (rt_pid == 0) {
177+
close(ext_ready[0]);
178+
close(ext_ready[1]);
179+
close(rt_ready[0]);
143180
set_affinity(CORE_ID);
144181
set_sched(SCHED_FIFO, 50);
182+
signal_ready(rt_ready[1]);
145183
process_func();
146184
exit(0);
147185
} else if (rt_pid < 0) {
148186
perror("fork for RT task");
149187
ksft_exit_fail();
150188
}
151189

190+
/*
191+
* Wait for both children to complete their setup (affinity and
192+
* scheduling policy) before starting the measurement window.
193+
* This prevents flaky failures caused by the RT child's setup
194+
* time eating into the measurement period.
195+
*/
196+
close(ext_ready[1]);
197+
close(rt_ready[1]);
198+
wait_ready(ext_ready[0]);
199+
wait_ready(rt_ready[0]);
200+
152201
/* Let the processes run for the specified time */
153202
sleep(RUN_TIME);
154203

0 commit comments

Comments
 (0)