[PATCH 1/3] tools/sched_ext: Increment nr_queued when a task is queued to user space

From: Wanwu Li

Date: Thu Sep 24 2026 - 10:37:51 EST


userland_update_idle() decides whether a CPU going idle must wake the
user-space scheduler with "if (nr_queued || nr_scheduled)", where
nr_queued is documented -- both in its declaration and in the NOTE in
userland_update_idle() -- to be incremented by the BPF component when
a task is queued to user space. But enqueue_task_in_user_space()
never increments it: a successful push only bumps the nr_user_enqueues
stats counter, so nr_queued stays 0 forever and the check silently
degrades to nr_scheduled alone. Tasks sitting in the enqueued map,
not yet drained by the user-space scheduler, are invisible to a CPU
going idle.

Increment nr_queued when the push succeeds; the user-space side
already clears it once the map is drained, as documented.

Fixes: cc4448d0856d ("tools/sched_ext: add scx_userland scheduler")
Signed-off-by: Wanwu Li <liwanwu@xxxxxxxxxx>
---
tools/sched_ext/scx_userland.bpf.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/sched_ext/scx_userland.bpf.c b/tools/sched_ext/scx_userland.bpf.c
index f29862b89386..648c6bd230eb 100644
--- a/tools/sched_ext/scx_userland.bpf.c
+++ b/tools/sched_ext/scx_userland.bpf.c
@@ -197,6 +197,7 @@ static void enqueue_task_in_user_space(struct task_struct *p, u64 enq_flags)
scx_bpf_dsq_insert(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags);
} else {
__sync_fetch_and_add(&nr_user_enqueues, 1);
+ __sync_fetch_and_add(&nr_queued, 1);
set_usersched_needed();
}
}
--
2.25.1