Re: [PATCH 19/17] sched_ext: Fix the stall watchdog blaming a bypassing owner for a stuck task
From: Andrea Righi
Date: Sun Oct 25 2026 - 11:53:11 EST
Hi Tejun,
On Fri, Oct 23, 2026 at 10:06:40AM -1000, Tejun Heo wrote:
> check_rq_for_timeouts() blames a stall on the scheduler whose DSQ the task
> sits on, and on the task's owner when the DSQ has none. A bypassed task can
> sit on the rescue DSQ or the local DSQ, and the blame then lands on its
> owner. The owner is bypassing and places nothing. The host, the nearest
> ancestor that is not bypassing, runs the bypassed tasks.
>
> That matters when the owner is already exiting, during its own disable for
> one. __scx_exit() on it is a no-op, the watchdog still ends its pass, and
> nothing is ejected. If the host is not running the bypassed tasks, the
> owner's disable, which waits on them, may never finish.
>
> Blame the host for a stuck task whose owner is bypassing. Ejecting the host
> re-hosts the bypassed subtree one level up. A task whose owner is not
> bypassing keeps the blame on the owner, and with every ancestor bypassing,
> scx_exec_sched() gives the root. A task on the host's bypass DSQ already led
> to the host through dsq->sched.
>
> The rescue overload accounting keeps charging the owner. Overload going
> unanswered while the owner exits is acceptable.
>
> Fixes: 2c91169377f4 ("sched_ext: Blame the DSQ's owning scheduler for a runnable stall")
> Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
> Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
> ---
> kernel/sched/ext/ext.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
> index 8241cf374ef9..ae5e8861ca0a 100644
> --- a/kernel/sched/ext/ext.c
> +++ b/kernel/sched/ext/ext.c
> @@ -4376,9 +4376,16 @@ static bool check_rq_for_timeouts(struct rq *rq)
> * ancestor's bypass DSQ while the owner is bypassing.
> * Blame the drainer. The local DSQ is consumed by the
> * cpu itself and keeps blame on the owner.
> + *
> + * A bypassing owner places nothing, and its tasks run
> + * through the host even from the rescue DSQ or the
> + * local DSQ. Blame the host. Blaming an owner that is
> + * already exiting would eject nothing.
> */
> if (dsq && dsq->sched && dsq->id != SCX_DSQ_LOCAL)
> sch = dsq->sched;
> + else if (scx_bypassing(sch, cpu_of(rq)))
> + sch = scx_exec_sched(sch, cpu_of(rq));
Should we recheck watchdog_timeout after changing sch?
The stall test above uses the task owner's timeout. So, a bypassing
child with a short timeout could potentially cause its host to be
ejected before the host's own timeout expires.
Thanks,
-Andrea
>
> __scx_exit(sch, SCX_EXIT_ERROR_STALL, 0, cpu_of(rq),
> "%s[%d] failed to run for %u.%03us",
> --
> 2.56.0
>