[PATCH 20/17] sched_ext: Fix a lone IMMED task waiting behind a kept prev
From: Tejun Heo
Date: Fri Oct 23 2026 - 16:10:20 EST
While dispatch is in progress, rq_is_open() returns true and dsq_inc_nr()
schedules no reenqueue for an IMMED task inserted on an empty local DSQ. The
check at the end of dispatch_one() catches up only when more than one task
is queued, so a dispatch that keeps prev leaves a lone IMMED task behind:
1. a parent's ops.dispatch() sub-dispatches into a child, which consumes a
task with SCX_ENQ_IMMED onto the empty local DSQ
2. the parent extends prev's slice and dispatch keeps prev
3. the local DSQ holds one task, so no reenqueue is scheduled
The IMMED task waits on the local DSQ behind prev instead of going back to
be placed again.
Schedule the reenqueue when dispatch keeps prev and an IMMED task is queued.
With prev keeping the cpu, even a lone IMMED task can't run right away.
Fixes: 98d709cba319 ("sched_ext: Implement SCX_ENQ_IMMED")
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
---
kernel/sched/ext/ext.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index ae5e8861ca0a..25f3788605eb 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -3464,8 +3464,12 @@ static enum scx_dsp_verdict dispatch_one(struct rq *rq, struct task_struct *prev
*
* - A non-IMMED HEAD task can get queued in front of an IMMED task
* between the IMMED queueing and the subsequent scheduling event.
+ *
+ * - Dispatch can keep prev with a lone IMMED task queued meanwhile. The
+ * task can't run right away behind prev.
*/
- if (unlikely(rq->scx.local_dsq.nr > 1 && rq->scx.nr_immed))
+ if (unlikely((rq->scx.local_dsq.nr > 1 || verdict == SCX_DSP_PREV) &&
+ rq->scx.nr_immed))
scx_schedule_reenq_local(rq, 0);
rq->scx.flags &= ~SCX_RQ_IN_DISPATCH;
--
2.56.0