summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2026-10-27 04:08:48 -1000
committerTejun Heo <tj@kernel.org>2026-10-27 09:40:56 -1000
commitb7723dedac0e92e5a74e89cb800a0083c2ab9ee2 (patch)
tree3715023d8e28da0ee583fd54771ca0f20268721e /kernel
parenta298fd5f4ee8f7e80c4dc74d9c501c22a037c6b6 (diff)
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 <sashiko-bot@kernel.org> Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Andrea Righi <arighi@nvidia.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/ext/sub.c13
1 files changed, 9 insertions, 4 deletions
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)
{