[tip: sched/core] sched/core: Drop mutex locks before proxy rescheduling
From: tip-bot2 for Andrea Righi
Date: Mon Sep 28 2026 - 03:02:52 EST
The following commit has been merged into the sched/core branch of tip:
Commit-ID: 313b652837d0541684680a7d07a95c5560441d4f
Gitweb: https://git.kernel.org/tip/313b652837d0541684680a7d07a95c5560441d4f
Author: Andrea Righi <arighi@xxxxxxxxxx>
AuthorDate: Tue, 22 Sep 2026 18:51:40 +02:00
Committer: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
CommitterDate: Mon, 28 Sep 2026 08:44:38 +02:00
sched/core: Drop mutex locks before proxy rescheduling
find_proxy_task() can call proxy_resched_idle() from return
expressions inside mutex wait_lock and blocked task lock guard scopes.
Return expressions are evaluated before scoped guards are released, so
proxy_resched_idle() invokes scheduling-class callbacks while both raw
spinlocks are held.
Route these cases through a common label outside the guard scopes. The
common label is required because a direct return would evaluate
proxy_resched_idle() before guard cleanup and run the class callbacks
under the proxy-exec locks again.
This is a preparatory change to support proxy execution with sched_ext.
Signed-off-by: Andrea Righi <arighi@xxxxxxxxxx>
Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
Reviewed-by: K Prateek Nayak <kprateek.nayak@xxxxxxx>
Link: https://patch.msgid.link/20260922165445.943315-2-arighi@xxxxxxxxxx
---
kernel/sched/core.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index ee9b443..f34e73c 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6980,7 +6980,7 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
if (!READ_ONCE(owner->on_rq) || owner->se.sched_delayed) {
/* XXX Don't handle blocked owners/delayed dequeue yet */
if (curr_in_chain)
- return proxy_resched_idle(rq);
+ goto resched_idle;
__clear_task_blocked_on(p, NULL);
goto deactivate;
}
@@ -6992,7 +6992,7 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
* and leave that CPU to sort things out.
*/
if (curr_in_chain)
- return proxy_resched_idle(rq);
+ goto resched_idle;
goto migrate_task;
}
@@ -7005,7 +7005,7 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
* case we should end up back in find_proxy_task(), this time
* hopefully with all relevant tasks already enqueued.
*/
- return proxy_resched_idle(rq);
+ goto resched_idle;
}
/*
@@ -7042,7 +7042,7 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
* So schedule rq->idle so that ttwu_runnable() can get the rq
* lock and mark owner as running.
*/
- return proxy_resched_idle(rq);
+ goto resched_idle;
}
/*
* OK, now we're absolutely sure @owner is on this
@@ -7062,6 +7062,8 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
}
return owner;
+resched_idle:
+ return proxy_resched_idle(rq);
deactivate:
proxy_deactivate(rq, p);
return NULL;