From: Tao Cui userland_dispatch() pops up to MAX_ENQUEUED_TASKS pids from the dispatched map and inserts each task into the global DSQ without consulting scx_bpf_dispatch_nr_slots(). The kernel's dispatch buffer holds 32 slots against MAX_ENQUEUED_TASKS (4096), so a single full dispatch round overflows it long before that many tasks pile up between dispatch rounds the insert past the buffer limit aborts the whole scheduler. Every other tools scheduler that loops on scx_bpf_dsq_insert() (scx_central, scx_qmap) checks the remaining slot count; scx_userland is the odd one out. Break out when the buffer is exhausted and leave the remaining tasks queued for the next dispatch round. Fixes: cc4448d0856d ("tools/sched_ext: add scx_userland scheduler") Signed-off-by: Tao Cui --- tools/sched_ext/scx_userland.bpf.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/sched_ext/scx_userland.bpf.c b/tools/sched_ext/scx_userland.bpf.c index f29862b89386..0a6daad84528 100644 --- a/tools/sched_ext/scx_userland.bpf.c +++ b/tools/sched_ext/scx_userland.bpf.c @@ -233,6 +233,14 @@ void BPF_STRUCT_OPS(userland_dispatch, s32 cpu, struct task_struct *prev) s32 pid; struct task_struct *p; + /* + * The dispatch buffer is limited. When it runs out, leave the + * remaining tasks queued for the next dispatch round instead + * of inserting past the limit and aborting the scheduler. + */ + if (!scx_bpf_dispatch_nr_slots()) + break; + if (bpf_map_pop_elem(&dispatched, &pid)) break; -- 2.53.0 base-commit: 5b740a72b55c4267ba4d8010f17dde26b26f52d3