]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
sched: Audit MOVE vs balance_callbacks
authorPeter Zijlstra <peterz@infradead.org>
Thu, 15 Jan 2026 08:17:49 +0000 (09:17 +0100)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 15 Jan 2026 20:57:53 +0000 (21:57 +0100)
The {DE,EN}QUEUE_MOVE flag indicates a task is allowed to change
priority, which means there could be balance callbacks queued.

Therefore audit all MOVE users and make sure they do run balance
callbacks before dropping rq-lock.

Fixes: 6455ad5346c9 ("sched: Move sched_class::prio_changed() into the change pattern")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Pierre Gondois <pierre.gondois@arm.com>
Tested-by: Juri Lelli <juri.lelli@redhat.com>
Link: https://patch.msgid.link/20260114130528.GB831285@noisy.programming.kicks-ass.net
kernel/sched/core.c
kernel/sched/ext.c
kernel/sched/sched.h

index 842a3adaf746744d32b328ad01f79d4f7a359cea..4d925d7ad097e1e6ee15f18c65ec299d8d4eb344 100644 (file)
@@ -4950,7 +4950,7 @@ struct balance_callback *splice_balance_callbacks(struct rq *rq)
        return __splice_balance_callbacks(rq, true);
 }
 
-static void __balance_callbacks(struct rq *rq, struct rq_flags *rf)
+void __balance_callbacks(struct rq *rq, struct rq_flags *rf)
 {
        if (rf)
                rq_unpin_lock(rq, rf);
@@ -9126,6 +9126,8 @@ void sched_move_task(struct task_struct *tsk, bool for_autogroup)
 
        if (resched)
                resched_curr(rq);
+
+       __balance_callbacks(rq, &rq_guard.rf);
 }
 
 static struct cgroup_subsys_state *
index 8f6d8d7f895ccc494414e971d370229da7c7ffe1..afe28c04d5aa73b582dba2535e86d3844318f48a 100644 (file)
@@ -545,6 +545,7 @@ static void scx_task_iter_start(struct scx_task_iter *iter)
 static void __scx_task_iter_rq_unlock(struct scx_task_iter *iter)
 {
        if (iter->locked_task) {
+               __balance_callbacks(iter->rq, &iter->rf);
                task_rq_unlock(iter->rq, iter->locked_task, &iter->rf);
                iter->locked_task = NULL;
        }
index e885a935b716258687323d735d71efa099bcab25..93fce4bbff5eac1d4719394e89dfae886b74d865 100644 (file)
@@ -2388,7 +2388,8 @@ extern const u32          sched_prio_to_wmult[40];
  *                should preserve as much state as possible.
  *
  * MOVE - paired with SAVE/RESTORE, explicitly does not preserve the location
- *        in the runqueue.
+ *        in the runqueue. IOW the priority is allowed to change. Callers
+ *        must expect to deal with balance callbacks.
  *
  * NOCLOCK - skip the update_rq_clock() (avoids double updates)
  *
@@ -3969,6 +3970,8 @@ extern void enqueue_task(struct rq *rq, struct task_struct *p, int flags);
 extern bool dequeue_task(struct rq *rq, struct task_struct *p, int flags);
 
 extern struct balance_callback *splice_balance_callbacks(struct rq *rq);
+
+extern void __balance_callbacks(struct rq *rq, struct rq_flags *rf);
 extern void balance_callbacks(struct rq *rq, struct balance_callback *head);
 
 /*