From: sashiko-bot@kernel.org
To: "Tejun Heo" <tj@kernel.org>, sched-ext@lists.linux.dev
Subject: Re: [PATCH 04/17] sched_ext: Fix bypassed tasks looping on a host without SCX_CAP_ENQ
Date: Fri, 23 Oct 2026 18:50:45 +0000 [thread overview]
Message-ID: <sashiko-outbox-183085@kernel.org> (raw)
In-Reply-To: <20261023175608.4120910-5-tj@kernel.org>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] sched_ext: missing IMMED reenqueue in dispatch_one() on SCX_DSP_PREV
--
commit 8162142ab19efe38b37c48e80241c382a88435ec
Author: Tejun Heo <tj@kernel.org>
sched_ext: Fix bypassed tasks looping on a host without SCX_CAP_ENQ
This commit updates scx_dispatch_sched() to pass SCX_ENQ_IMMED when consuming
tasks from a scheduler's bypass DSQ so that a host holding only
SCX_CAP_ENQ_IMMED (SCX_CAP_BASE) can run bypassed tasks without needing
SCX_CAP_ENQ.
> diff --git a/kernel/sched/ext/inlines.h b/kernel/sched/ext/inlines.h
> index 8de9d8fb4b25f..1e39d12678c4d 100644
> --- a/kernel/sched/ext/inlines.h
> +++ b/kernel/sched/ext/inlines.h
> @@ -39,10 +39,18 @@ scx_dispatch_sched(struct scx_sched *sch, struct rq *rq,
> if (scx_consume_global_dsq(sch, rq))
> return SCX_DSP_LOCAL;
>
> + /*
> + * A bypass consume puts a task on the cpu being dispatched for, to run
> + * right away. That is an IMMED insert and needs only
> + * %SCX_CAP_ENQ_IMMED, the base cap. Dispatch descends into @sch only on
> + * a cpu where @sch holds the base cap, so @sch holds it here. The same
> + * holds for the consume at the end of this function.
> + */
> if (scx_bypass_dsp_enabled(sch)) {
> /* if @sch is bypassing, only the bypass DSQs are active */
> if (scx_bypassing(sch, cpu)) {
> - if (scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu), 0))
> + if (scx_consume_dispatch_q(sch, rq, scx_bypass_dsq(sch, cpu),
> + SCX_ENQ_IMMED))
> return SCX_DSP_LOCAL;
> return SCX_DSP_NONE;
> }
[Severity: Medium]
Can a bypassed task consumed with SCX_ENQ_IMMED get left waiting on
rq->scx.local_dsq without being reenqueued when dispatch_one() finishes with
SCX_DSP_PREV?
During dispatch_one(), SCX_RQ_IN_DISPATCH is set on rq->scx.flags, which makes
rq_is_open() unconditionally return true so that resolution of whether prev
keeps running is deferred until the end of dispatch_one():
kernel/sched/ext/ext.c:rq_is_open() {
...
if (rq->scx.flags & SCX_RQ_IN_DISPATCH)
return true;
...
}
If a parent scheduler's ops.dispatch() calls scx_bpf_sub_dispatch() on a child
while rq->scx.local_dsq is empty and scx_dispatch_sched() consumes a single
task from scx_bypass_dsq(child, cpu) with SCX_ENQ_IMMED (or if
scx_process_sync_ecaps() queues a single SCX_ENQ_IMMED task during its
callbacks), dsq_inc_nr() sees dsq->nr == 1 and rq_is_open() == true, so it
does not call scx_schedule_reenq_local():
kernel/sched/ext/ext.c:dsq_inc_nr() {
...
if (p->scx.flags & SCX_TASK_IMMED) {
...
rq->scx.nr_immed++;
if (unlikely(dsq->nr > 1 || !rq_is_open(rq, enq_flags)))
scx_schedule_reenq_local(rq, 0);
}
}
If the parent's ops.dispatch() also extends prev->scx.slice (or prev already
had slice left after scx_process_sync_ecaps()), scx_dispatch_sched() returns
SCX_DSP_PREV before checking rq->scx.local_dsq.nr:
kernel/sched/ext/inlines.h:scx_dispatch_sched() {
...
scx_flush_dispatch_buf(sch, rq);
if ((prev->scx.flags & SCX_TASK_QUEUED) && prev->scx.slice)
return SCX_DSP_PREV;
if (rq->scx.local_dsq.nr)
return SCX_DSP_LOCAL;
...
}
At the has_tasks label in dispatch_one(), the check only tests whether
rq->scx.local_dsq.nr > 1:
kernel/sched/ext/ext.c:dispatch_one() {
...
has_tasks:
if (unlikely(rq->scx.local_dsq.nr > 1 && rq->scx.nr_immed))
scx_schedule_reenq_local(rq, 0);
rq->scx.flags &= ~SCX_RQ_IN_DISPATCH;
return verdict;
}
Because prev is not on local_dsq, rq->scx.local_dsq.nr is 1, so
scx_schedule_reenq_local() is not called, and do_pick_task_scx() keeps running
prev while the single SCX_TASK_IMMED task remains queued on local_dsq (even
when its scheduler lacks SCX_CAP_ENQ).
Should the check at has_tasks in dispatch_one() also trigger
scx_schedule_reenq_local() when verdict == SCX_DSP_PREV and rq->scx.nr_immed
is non-zero, such as checking (rq->scx.local_dsq.nr > 1 || verdict ==
SCX_DSP_PREV) && rq->scx.nr_immed?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261023175608.4120910-1-tj@kernel.org?part=4
next prev parent reply other threads:[~2026-10-23 18:50 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-23 17:55 [PATCHSET v3 sched_ext/for-7.4] sched_ext: Fix bypassed sub-scheduler tasks stalling when the host lacks caps Tejun Heo
2026-10-23 17:55 ` [PATCH 01/17] sched_ext: Pack scx_ent_flags' multi-bit fields at the top Tejun Heo
2026-10-23 17:55 ` [PATCH 02/17] sched_ext: Clear holding_cpu where the claim is confirmed Tejun Heo
2026-10-23 17:55 ` [PATCH 03/17] sched_ext: Fix bypassed tasks stranded by the reenqueue limit Tejun Heo
2026-10-23 17:55 ` [PATCH 04/17] sched_ext: Fix bypassed tasks looping on a host without SCX_CAP_ENQ Tejun Heo
2026-10-23 18:50 ` sashiko-bot [this message]
2026-10-23 19:08 ` Tejun Heo
2026-10-23 17:55 ` [PATCH 05/17] sched_ext: Move refill_task_slice_dfl() below apply_slice_vtime() Tejun Heo
2026-10-23 17:55 ` [PATCH 06/17] sched_ext: Fix rescue served time disagreeing with the slice under proxy execution Tejun Heo
2026-10-23 17:55 ` [PATCH 07/17] sched_ext: Restore a rescuee's slice after ops.stopping() Tejun Heo
2026-10-23 17:55 ` [PATCH 08/17] sched_ext: Fix a cpu idling with a runnable rescuee Tejun Heo
2026-10-23 17:56 ` [PATCH 09/17] sched_ext: Mark the rescue grant as a kernel slice with SCX_TASK_KERNEL_SLICE Tejun Heo
2026-10-23 17:56 ` [PATCH 10/17] sched_ext: Refuse extending a kernel slice Tejun Heo
2026-10-23 17:56 ` [PATCH 11/17] sched_ext: Fix a cpu idling after put_prev_task_scx() queues its task on the local DSQ Tejun Heo
2026-10-23 17:56 ` [PATCH 12/17] sched_ext: Expire prev's slice in dispatch_one() under bypass Tejun Heo
2026-10-23 17:56 ` [PATCH 13/17] sched_ext: Fix bypassed tasks stalling when the host lacks SCX_CAP_BASE Tejun Heo
2026-10-23 19:02 ` sashiko-bot
2026-10-23 20:06 ` Tejun Heo
2026-10-23 17:56 ` [PATCH 14/17] sched_ext: Fix the bypass load balancer stranding tasks on cpus where " Tejun Heo
2026-10-23 17:56 ` [PATCH 15/17] sched_ext: Factor out bypass_lb_move() and insert with the donor DSQ unlocked Tejun Heo
2026-10-23 17:56 ` [PATCH 16/17] sched_ext: Let the bypass load balancer move tasks homed on other cpus Tejun Heo
2026-10-23 17:56 ` [PATCH 17/17] sched_ext: Fix queued bypassed tasks stalling when the host loses SCX_CAP_BASE Tejun Heo
2026-10-25 15:47 ` Andrea Righi
2026-10-26 21:31 ` Tejun Heo
2026-10-23 20:06 ` [PATCH 18/17] sched_ext: Fix use-after-free of a NONE rescuee leaving sched_ext Tejun Heo
2026-10-23 20:06 ` [PATCH 19/17] sched_ext: Fix the stall watchdog blaming a bypassing owner for a stuck task Tejun Heo
2026-10-25 15:52 ` Andrea Righi
2026-10-26 21:31 ` Tejun Heo
2026-10-23 20:10 ` [PATCH 20/17] sched_ext: Fix a lone IMMED task waiting behind a kept prev Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-183085@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=sched-ext@lists.linux.dev \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox