Re: [PATCH 1/2] sched_ext: Add scx_tickbug, a scheduler that holds a task on an idle CPU
From: Radu Toader
Date: Fri Nov 06 2026 - 21:16:13 EST
All three are right. This patch is dropped from v2 at Tejun's request,
so none of it lands, but the fixes are worth recording for anyone who
takes the reproducer out of the archive.
The starvation is a real bug, not a theoretical one. tickbug_enqueue()
routed to the local DSQ only tasks with PF_KTHREAD and
nr_cpus_allowed == 1, so a user task pinned with taskset went to
SHARED_DSQ; task_allowed_on_cpu() then stops any other CPU from taking
it, and tickbug_dispatch() returns before
scx_bpf_dsq_move_to_local(SHARED_DSQ, 0) for as long as nr_held_now is
non-zero. With the hand-off you describe that is unbounded and ends at
the 5 s watchdog, which contradicts the commit message. Your suggested
fix is what I used: dispatch anything with nr_cpus_allowed == 1 to its
local DSQ. A task pinned to a subset of CPUs containing the target CPU
is still delayed by the length of one hold, which -H bounds; the comment
now says that rather than implying the case is covered.
The sleepable comment was wrong twice over, as you note: the op is
declared with BPF_STRUCT_OPS() and not BPF_STRUCT_OPS_SLEEPABLE() as
scx_qmap and scx_sdt do, and since 136deea435dc bpf_task_storage_get()
allocates with bpf_map_kmalloc_nolock() regardless. The comment is
dropped rather than the declaration changed, since nothing here needs to
sleep.
The README now says the scheduler reproduces the condition
tick_irq_exit() handles and can be used to check it, which also matches
the past tense the BPF header comment was already using.
Disclosure: this reply was written by Claude Opus 5 (Claude Code) and
sent on my behalf, in the same session as the patch; the patch changelog
carries the same note.