* [PATCH 0/5] sched_ext: selftest infrastructure fixes
@ 2026-10-09 13:40 Tao Cui
0 siblings, 0 replies; 3+ messages in thread
From: Tao Cui @ 2026-10-09 13:40 UTC (permalink / raw)
To: Tejun Heo
Cc: David Vernet, Andrea Righi, Changwoo Min, sched-ext, cui.tao,
Tao Cui
From: Tao Cui <cuitao@kylinos.cn>
The sched_ext selftests pass vacuously or hang in several failure
scenarios: a scheduler that dies mid-test freezes the state the test
asserts on, EXIT_KIND() silently maps missing BTF enums to
SCX_EXIT_NONE, waits for scheduler exit are unbounded, attach
failures in the reload stress test are swallowed, and an error path
in reload_loop destroys the skeleton under a still-running thread.
1. selftests/sched_ext: Fix reload_loop error-path use-after-free
If the second pthread_create() fails, run() returns and the
runner calls cleanup, which destroys the skeleton while the
first reload thread is still running do_reload_loop() and
dereferencing its maps. Set force_exit and join the first
thread before failing.
2. sched_ext: Add SCX_ECODE_RSN_CGROUP_OFFLINE to user_exit_info.h
Sync the tools-side exit code enum with the kernel; without it
userspace code has no name for this reason.
3. selftests/sched_ext: Fail loudly when EXIT_KIND is missing from
BTF. EXIT_KIND() resolves scx_exit_kind values through
__COMPAT_ENUM_OR_ZERO(), which maps a missing enum to 0 (==
SCX_EXIT_NONE), so on kernels whose BTF lacks the enum every
EXIT_KIND() comparison is meaningless. Resolve the value with
__COMPAT_read_enum() and fail the test when it is missing,
matching SCX_ECODE_VAL() and SCX_KIND_VAL(). The kick and
nohz_tick polling helpers switch to UEI_EXITED() so they keep
their semantics without a BTF lookup.
4. selftests/sched_ext: Add SCX_ASSERT_ALIVE and adopt it. A
scheduler that dies mid-test freezes the state that the test is
about to assert on, so the assertions can pass vacuously.
5. selftests/sched_ext: Bound exit waits and report reload_loop
failures. exit, prog_run and hotplug wait for the scheduler to
exit with no time bound; a scheduler that never exits hangs the
runner. Bound the waits to ~10s (iteration-based). reload_loop
skips bpf_map__attach_struct_ops() failures silently: measured
on a loaded host, 1125-1233 of 2048 iterations failed, all with
EBUSY (the single scheduler slot changing hands between the two
threads). Count the failures per thread and fail the test only
on unexpected errnos or when every attach failed.
Tao Cui (5):
selftests/sched_ext: Fix reload_loop error-path use-after-free
sched_ext: Add SCX_ECODE_RSN_CGROUP_OFFLINE to user_exit_info.h
selftests/sched_ext: Fail loudly when EXIT_KIND is missing from BTF
selftests/sched_ext: Add SCX_ASSERT_ALIVE and adopt it
selftests/sched_ext: Bound exit waits and report reload_loop failures
tools/sched_ext/include/scx/user_exit_info.h | 1 +
.../selftests/sched_ext/create_dsq.bpf.c | 8 +++
.../testing/selftests/sched_ext/create_dsq.c | 2 +
tools/testing/selftests/sched_ext/exit.c | 4 +-
tools/testing/selftests/sched_ext/hotplug.c | 12 +++--
.../sched_ext/init_enable_count.bpf.c | 8 +++
.../selftests/sched_ext/init_enable_count.c | 13 +++++
tools/testing/selftests/sched_ext/kick.c | 8 +--
.../testing/selftests/sched_ext/maximal.bpf.c | 6 ++-
tools/testing/selftests/sched_ext/maximal.c | 2 +
tools/testing/selftests/sched_ext/nohz_tick.c | 6 +--
tools/testing/selftests/sched_ext/prog_run.c | 7 ++-
.../testing/selftests/sched_ext/reload_loop.c | 53 ++++++++++++++++---
tools/testing/selftests/sched_ext/scx_test.h | 48 ++++++++++++++++-
14 files changed, 155 insertions(+), 23 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 0/5] sched_ext: selftest infrastructure fixes
@ 2026-10-09 13:40 Tao Cui
2026-10-12 23:56 ` Tejun Heo
0 siblings, 1 reply; 3+ messages in thread
From: Tao Cui @ 2026-10-09 13:40 UTC (permalink / raw)
To: Tejun Heo
Cc: David Vernet, Andrea Righi, Changwoo Min, sched-ext, cui.tao,
Tao Cui
From: Tao Cui <cuitao@kylinos.cn>
The sched_ext selftests pass vacuously or hang in several failure
scenarios: a scheduler that dies mid-test freezes the state the test
asserts on, EXIT_KIND() silently maps missing BTF enums to
SCX_EXIT_NONE, waits for scheduler exit are unbounded, attach
failures in the reload stress test are swallowed, and an error path
in reload_loop destroys the skeleton under a still-running thread.
1. selftests/sched_ext: Fix reload_loop error-path use-after-free
If the second pthread_create() fails, run() returns and the
runner calls cleanup, which destroys the skeleton while the
first reload thread is still running do_reload_loop() and
dereferencing its maps. Set force_exit and join the first
thread before failing.
2. sched_ext: Add SCX_ECODE_RSN_CGROUP_OFFLINE to user_exit_info.h
Sync the tools-side exit code enum with the kernel; without it
userspace code has no name for this reason.
3. selftests/sched_ext: Fail loudly when EXIT_KIND is missing from
BTF. EXIT_KIND() resolves scx_exit_kind values through
__COMPAT_ENUM_OR_ZERO(), which maps a missing enum to 0 (==
SCX_EXIT_NONE), so on kernels whose BTF lacks the enum every
EXIT_KIND() comparison is meaningless. Resolve the value with
__COMPAT_read_enum() and fail the test when it is missing,
matching SCX_ECODE_VAL() and SCX_KIND_VAL(). The kick and
nohz_tick polling helpers switch to UEI_EXITED() so they keep
their semantics without a BTF lookup.
4. selftests/sched_ext: Add SCX_ASSERT_ALIVE and adopt it. A
scheduler that dies mid-test freezes the state that the test is
about to assert on, so the assertions can pass vacuously.
5. selftests/sched_ext: Bound exit waits and report reload_loop
failures. exit, prog_run and hotplug wait for the scheduler to
exit with no time bound; a scheduler that never exits hangs the
runner. Bound the waits to ~10s (iteration-based). reload_loop
skips bpf_map__attach_struct_ops() failures silently: measured
on a loaded host, 1125-1233 of 2048 iterations failed, all with
EBUSY (the single scheduler slot changing hands between the two
threads). Count the failures per thread and fail the test only
on unexpected errnos or when every attach failed.
Tao Cui (5):
selftests/sched_ext: Fix reload_loop error-path use-after-free
sched_ext: Add SCX_ECODE_RSN_CGROUP_OFFLINE to user_exit_info.h
selftests/sched_ext: Fail loudly when EXIT_KIND is missing from BTF
selftests/sched_ext: Add SCX_ASSERT_ALIVE and adopt it
selftests/sched_ext: Bound exit waits and report reload_loop failures
tools/sched_ext/include/scx/user_exit_info.h | 1 +
.../selftests/sched_ext/create_dsq.bpf.c | 8 +++
.../testing/selftests/sched_ext/create_dsq.c | 2 +
tools/testing/selftests/sched_ext/exit.c | 4 +-
tools/testing/selftests/sched_ext/hotplug.c | 12 +++--
.../sched_ext/init_enable_count.bpf.c | 8 +++
.../selftests/sched_ext/init_enable_count.c | 13 +++++
tools/testing/selftests/sched_ext/kick.c | 8 +--
.../testing/selftests/sched_ext/maximal.bpf.c | 6 ++-
tools/testing/selftests/sched_ext/maximal.c | 2 +
tools/testing/selftests/sched_ext/nohz_tick.c | 6 +--
tools/testing/selftests/sched_ext/prog_run.c | 7 ++-
.../testing/selftests/sched_ext/reload_loop.c | 53 ++++++++++++++++---
tools/testing/selftests/sched_ext/scx_test.h | 48 ++++++++++++++++-
14 files changed, 155 insertions(+), 23 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH 0/5] sched_ext: selftest infrastructure fixes
2026-10-09 13:40 Tao Cui
@ 2026-10-12 23:56 ` Tejun Heo
0 siblings, 0 replies; 3+ messages in thread
From: Tejun Heo @ 2026-10-12 23:56 UTC (permalink / raw)
To: Tao Cui; +Cc: David Vernet, Andrea Righi, Changwoo Min, sched-ext, Tao Cui
Hello, Tao.
The following is a Claude-generated review.
On Fri, Oct 09, 2026 at 09:40:59PM +0800, Tao Cui wrote:
> 1. selftests/sched_ext: Fix reload_loop error-path use-after-free
Looks good. Inside the if (err) block, SCX_FAIL() reads better than
SCX_FAIL_IF(err, ...).
> 2. sched_ext: Add SCX_ECODE_RSN_CGROUP_OFFLINE to user_exit_info.h
Can you name the commit in the description? It's ebeca1f930ea ("sched_ext:
Introduce cgroup sub-sched support").
> 3. selftests/sched_ext: Fail loudly when EXIT_KIND is missing from
> BTF. EXIT_KIND() resolves scx_exit_kind values through
> __COMPAT_ENUM_OR_ZERO(), which maps a missing enum to 0 (==
> SCX_EXIT_NONE), so on kernels whose BTF lacks the enum every
> EXIT_KIND() comparison is meaningless.
struct scx_exit_info carries enum scx_exit_kind, so any BTF that loads the
skeleton has the enum. What can be missing is an enumerator, and the four
the tests use today exist on every sched_ext kernel. On a kernel missing
one, the comparisons against SCX_EXIT_NONE get the right value from the
fallback, the SCX_EQ()s against UNREG/UNREG_BPF/ERROR fail with a confusing
message, and the only vacuous pass is the error poll in kick.c.
The new EXIT_KIND() is also SCX_KIND_VAL() with a different message. If
you want to keep the patch, maybe define one in terms of the other?
With a return hidden in the macro, the remaining
kind != EXIT_KIND(SCX_EXIT_NONE) sites (allowed_cpus, cgroup_nr_cpus,
cyclic_kick_wait, enq_blocked) jump over their goto cleanup on a miss, and
invalid_one() resolves error_kind after the gated worker is spawned.
Converting those sites to UEI_EXITED() like the polling helpers and
hoisting the lookup above the spawn would close that.
The <unistd.h> include is unused in this patch, and compat.h already pulls
it in.
> 4. selftests/sched_ext: Add SCX_ASSERT_ALIVE and adopt it.
Looks good. Can SCX_ASSERT_ALIVE() print uei.msg too? That's where the
actual error text ends up. UEI_REPORT() already does that.
> 5. selftests/sched_ext: Bound exit waits and report reload_loop
> failures.
On timeout, exit.c returns with the link and the skel still open. The
scheduler that didn't exit stays attached for the rest of the runner
process, so every later test fails to attach with EBUSY and the real
failure is buried. prog_run and hotplug destroy the link on their timeout
paths. Can exit.c do the same, plus exit__destroy()?
In reload_loop, SCX_FAIL_IF(unexpected_errno, ...) returns before the
printf(), so the ", unexpected errno" arm is dead, and the EBUSY count then
prints on every run. 2048 of 2048 failing is also a weak bar; "at least one
success per thread" would say the same thing more sharply. Would you split
the timed wait and the reload_loop accounting into two patches?
Nits: two stray blank lines after setup(), and the two #defines could be an
enum.
Can you note the base and how the series was tested in the cover?
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-12 23:56 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-09 13:40 [PATCH 0/5] sched_ext: selftest infrastructure fixes Tao Cui
-- strict thread matches above, loose matches on Subject: below --
2026-10-09 13:40 Tao Cui
2026-10-12 23:56 ` Tejun Heo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.