Skip to content

Commit abc40cc

Browse files
author
Peter Zijlstra
committed
sched/proxy: Optimize try_to_wake_up()
The reason for the clause in try_to_wake_up() is, per its comment, that find_proxy_task()'s proxy_deactivate() is not always called with a cleared p->blocked_on. However, that seems silly and easily cured. Make sure to always call proxy_deactivate() with a cleared p->blocked_on such that we might remove this clause from the common wake-up path. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: John Stultz <jstultz@google.com> Link: https://patch.msgid.link/20260526113322.244729903%40infradead.org
1 parent 1628b25 commit abc40cc

1 file changed

Lines changed: 4 additions & 10 deletions

File tree

kernel/sched/core.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4343,14 +4343,6 @@ int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
43434343
*/
43444344
WRITE_ONCE(p->__state, TASK_WAKING);
43454345

4346-
/*
4347-
* We never clear the blocked_on relation on proxy_deactivate.
4348-
* If we don't clear it here, we have TASK_RUNNING + p->blocked_on
4349-
* when waking up. Since this is a fully blocked, off CPU task
4350-
* waking up, it should be safe to clear the blocked_on relation.
4351-
*/
4352-
if (task_is_blocked(p))
4353-
clear_task_blocked_on(p, NULL);
43544346
/*
43554347
* If the owning (remote) CPU is still in the middle of schedule() with
43564348
* this task as prev, considering queueing p on the remote CPUs wake_list
@@ -6739,6 +6731,7 @@ static void proxy_deactivate(struct rq *rq, struct task_struct *donor)
67396731
unsigned long state = READ_ONCE(donor->__state);
67406732

67416733
WARN_ON_ONCE(state == TASK_RUNNING);
6734+
WARN_ON_ONCE(donor->blocked_on);
67426735
/*
67436736
* Because we got donor from pick_next_task(), it is *crucial*
67446737
* that we call proxy_resched_idle() before we deactivate it.
@@ -6864,9 +6857,9 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
68646857
for (p = donor; (mutex = p->blocked_on); p = owner) {
68656858
/* if its PROXY_WAKING, do return migration or run if current */
68666859
if (mutex == PROXY_WAKING) {
6860+
clear_task_blocked_on(p, PROXY_WAKING);
68676861
if (task_current(rq, p)) {
68686862
p->is_blocked = 0;
6869-
clear_task_blocked_on(p, PROXY_WAKING);
68706863
return p;
68716864
}
68726865
goto deactivate;
@@ -6900,9 +6893,9 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
69006893
* and return p (if it is current and safe to
69016894
* just run on this rq), or return-migrate the task.
69026895
*/
6896+
__clear_task_blocked_on(p, NULL);
69036897
if (task_current(rq, p)) {
69046898
p->is_blocked = 0;
6905-
__clear_task_blocked_on(p, NULL);
69066899
return p;
69076900
}
69086901
goto deactivate;
@@ -6912,6 +6905,7 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
69126905
/* XXX Don't handle blocked owners/delayed dequeue yet */
69136906
if (curr_in_chain)
69146907
return proxy_resched_idle(rq);
6908+
__clear_task_blocked_on(p, NULL);
69156909
goto deactivate;
69166910
}
69176911

0 commit comments

Comments
 (0)