[RFC][PATCH 1/2] sched: proxy-exec: Fix tasks being left unpushable from proxy_tag_curr()
From: John Stultz
Date: Wed Mar 04 2026 - 01:40:00 EST
With proxy-execution, when we are running a lock owner on behalf
of a waiting donor, we call proxy_tag_curr() to ensure that both
the selected donor task *and* the owner we will run are taken
off the pushable lists. This avoids crashes where the running
task gets migrated away because only the donor was removed from
the pushable list.
However, K Prateek noticed that while we take the task off of
the pushable list, we don't actually return it to the pushable
list when we are done running it as a proxy on behalf of a donor
task.
Fix this in __schedule() by calling proxy_tag_curr() again on
the previously run task once we have switched the rq->curr
value. This will call dequeue/enqueue again which will allow
the task to be re-evaluated for being added to the pushable
list in the class scheduler.
Further optimizations to get rid of the dequeue/enqueue calls
for something more focused will follow.
NOTE: K Prateek also suggested that we should re-evaluate if
balance callbacks should be set when we allow prev to be
re-added to the pushable list, as pick_next_task() might have
seen no pushable tasks. I think this is a good idea, but I've
not yet addressed this.
Fixes: be39617e38e0 ("sched: Fix proxy/current (push,pull)ability")
Reported-by: K Prateek Nayak <kprateek.nayak@xxxxxxx>
Closes: https://lore.kernel.org/lkml/e735cae0-2cc9-4bae-b761-fcb082ed3e94@xxxxxxx/
Signed-off-by: John Stultz <jstultz@xxxxxxxxxx>
---
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Juri Lelli <juri.lelli@xxxxxxxxxx>
Cc: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
Cc: Dietmar Eggemann <dietmar.eggemann@xxxxxxx>
Cc: Valentin Schneider <vschneid@xxxxxxxxxx>
Cc: Johannes Weiner <hannes@xxxxxxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: Ben Segall <bsegall@xxxxxxxxxx>
Cc: Mel Gorman <mgorman@xxxxxxx>
Cc: Joel Fernandes <joelagnelf@xxxxxxxxxx>
Cc: Qais Yousef <qyousef@xxxxxxxxxxx>
Cc: Xuewen Yan <xuewen.yan94@xxxxxxxxx>
Cc: K Prateek Nayak <kprateek.nayak@xxxxxxx>
Cc: Suleiman Souhlal <suleiman@xxxxxxxxxx>
Cc: kuyo chang <kuyo.chang@xxxxxxxxxxxx>
Cc: hupu <hupu.gm@xxxxxxxxx>
Cc: zhidao su <suzhidao@xxxxxxxxxx>
Cc: soolaugust@xxxxxxxxx
Cc: kernel-team@xxxxxxxxxxx
---
kernel/sched/core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b7f77c165a6e0..55bafb1585eca 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6760,7 +6760,7 @@ static inline void proxy_tag_curr(struct rq *rq, struct task_struct *owner)
*/
static void __sched notrace __schedule(int sched_mode)
{
- struct task_struct *prev, *next;
+ struct task_struct *prev, *next, *prev_donor;
/*
* On PREEMPT_RT kernel, SM_RTLOCK_WAIT is noted
* as a preemption by schedule_debug() and RCU.
@@ -6779,7 +6779,7 @@ static void __sched notrace __schedule(int sched_mode)
cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr;
-
+ prev_donor = rq->donor;
schedule_debug(prev, preempt);
if (sched_feat(HRTICK) || sched_feat(HRTICK_DL))
@@ -6873,6 +6873,8 @@ static void __sched notrace __schedule(int sched_mode)
if (!task_current_donor(rq, next))
proxy_tag_curr(rq, next);
+ if (!(!preempt && prev_state) && prev != prev_donor)
+ proxy_tag_curr(rq, prev);
/*
* The membarrier system call requires each architecture
--
2.53.0.473.g4a7958ca14-goog