From b7723dedac0e92e5a74e89cb800a0083c2ab9ee2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 27 Oct 2026 04:08:48 -1000 Subject: sched_ext: Fix the rescue overload pick ejecting the wrong sub under bypass An earlier patch sends a bypassed task to rescue when its host lacks SCX_CAP_BASE on the cpu. The task's rescue time is charged to its owner, the bypassing sub, which is usually exiting. The overload pick skips exiting subs and ejects an unrelated sub or nobody. The host runs the task and lacks BASE, but carries none of the charge. Charge the sched running the rescuee, the host while the owner bypasses. SCX_EV_SUB_RESCUE already counts on that sched and the stall watchdog blames it. Reported-by: Sashiko Signed-off-by: Tejun Heo Reviewed-by: Andrea Righi --- kernel/sched/ext/sub.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c index e0aed3ce9735..068ca57d1bb7 100644 --- a/kernel/sched/ext/sub.c +++ b/kernel/sched/ext/sub.c @@ -479,9 +479,13 @@ void scx_rescue_charge(struct rq *rq, s64 delta_exec) rq->scx.rescue.budget -= delta_exec; - /* per-cpu usage average feeds the overload victim pick */ - pcpu = per_cpu_ptr(scx_task_sched(rq->scx.rescue.curr)->pcpu, - cpu_of(rq)); + /* + * The per-cpu usage average feeds the overload victim pick. Charge the + * sched running the rescuee, which is the host while the rescuee's + * owner is bypassing. + */ + pcpu = per_cpu_ptr(scx_exec_sched(scx_task_sched(rq->scx.rescue.curr), + cpu_of(rq))->pcpu, cpu_of(rq)); pcpu->rescue_avg = scx_rescue_decay_avg(pcpu) + delta_exec; if (!scx_rescue_slice_remaining(rq)) @@ -665,7 +669,8 @@ static bool scx_rescue_try_admit(struct rq *rq, struct task_struct *p) * If the oldest waiter on @rq's rescue DSQ has been queued for too long, rescue * demand on this cpu persistently exceeds the configured bandwidth. Eject the * sub with the highest recent rescue consumption instead of letting the - * scheduler stall path blame the waiter's owner, who may just be crowded out. + * scheduler stall path blame the sched running the waiter, which may just be + * crowded out. */ static void scx_rescue_check_overload(struct rq *rq) { -- cgit v1.2.3