From 3b1c7c74a6da97f86bdd31c66e8c592aa4372e16 Mon Sep 17 00:00:00 2001 From: Andrea Righi Date: Wed, 21 Oct 2026 09:05:35 +0200 Subject: [PATCH] sched/core: Avoid requeueing a singleton balance callback With proxy execution, __schedule() can call set_next_task_scx() with SNT_REPICK and then SNT_PICK for the same donor. Both calls queue the kick_sync balance callback while kick_sync_pending remains set. When the callback is the only list entry, its next pointer is NULL, so the existing duplicate check misses it. Queueing it again links it to itself and causes the wait to run twice. Also check whether the callback is already the head of the list to reject the second insertion. This covers the kick_sync callback because nothing else is queued between SNT_REPICK and SNT_PICK. Requeueing the tail of a longer list remains possible and is outside the scope of this fix. Fixes: e2859566ffbc ("sched_ext: Queue the kick_sync wait from set_next_task_scx()") Reported-by: Tejun Heo Link: https://lore.kernel.org/r/08cac02c604dd73ef96fc92eb29d692b@kernel.org Signed-off-by: Andrea Righi Acked-by: Tejun Heo Acked-by: Peter Zijlstra (Intel) Signed-off-by: Tejun Heo --- kernel/sched/sched.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 9e7993256c81..628765910934 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2175,7 +2175,8 @@ queue_balance_callback(struct rq *rq, * balance_push() is active, see the comment with * balance_push_callback. */ - if (unlikely(head->next || rq->balance_callback == &balance_push_callback)) + if (unlikely(head->next || rq->balance_callback == head || + rq->balance_callback == &balance_push_callback)) return; head->func = func;