[PATCH 01/10] sched/core: Drop mutex locks before proxy rescheduling
Andrea Righi <[email protected]>
| Newsgroups | dev.linux.lists.sched-ext,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
find_proxy_task() can call proxy_resched_idle() while holding a mutex wait_lock and the blocked task lock. Guard cleanup does not run until after the return expression is evaluated. proxy_resched_idle() invokes scheduling-class callbacks through put_prev_set_next_task(). Calling those callbacks with the mutex locks held prevents them from safely inspecting the proxy chain, as doing so may require acquiring the same locks. This is a preparatory change to support proxy execution in sched_ext. It leaves the guard scope before calling proxy_resched_idle() so sched_ext callbacks can safely inspect the proxy chain. Reviewed-by: K Prateek Nayak <[email protected]> Signed-off-by: Andrea Righi <[email protected]> --- 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 3cc6fb1d20547..0139cd4a8be7e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6923,7 +6923,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; } @@ -6935,7 +6935,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; } @@ -6948,7 +6948,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; } /* @@ -6985,7 +6985,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 @@ -6997,6 +6997,8 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf) WARN_ON_ONCE(owner && !owner->on_rq); return owner; +resched_idle: + return proxy_resched_idle(rq); deactivate: proxy_deactivate(rq, p); return NULL; -- 2.55.0