* [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31)
@ 2026-07-24 18:12 John Stultz
2026-07-24 18:12 ` [PATCH v31 1/9] sched/deadline: Ignore proxy-exec sched_yield() John Stultz
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: John Stultz, Joel Fernandes, Qais Yousef, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Valentin Schneider, Steven Rostedt, Ben Segall, Zimuzo Ezeozue,
Will Deacon, Waiman Long, Boqun Feng, Paul E. McKenney,
Metin Kaya, Xuewen Yan, K Prateek Nayak, Thomas Gleixner,
Daniel Lezcano, Suleiman Souhlal, kuyo chang, hupu, kernel-team
Hey All,
I wanted to send out another iteration of the next major
component of Proxy Execution: Sleeping Owner Handling.
As always, I’m trying to submit this larger work in smallish
digestible pieces. A quick overview of the journey so far:
1) prep patches
2) single rq proxying
3) simple donor migration
4) optimized donor migration
5) sleeping owner handling <- We are here!
6) chain level balancing
7) proxy rwsems
8) ...
In this chunk, there actually is more than just sleeping owner
handling: I’m including some core-scheduling fixes from Vasily
Gorbik and K Prateek, a DL fix from Christian, as well as an
optimization to chain migration left over from the last chunk.
But the substantial part of this chunk is the sleeping owner
handling, which addresses what to do when a task is blocked on a
mutex whose owner is sleeping. Since there is nothing we can do
to boost the sleeping owner at that point, we instead deactivate
and queue the waiter on a list attached to the owner. Then when
the owner wakes up, we will activate the waiters on the same
runqueue, so they can then boost the owner to run.
But since the simple sounding things hide subtlety, this ends up
being a pretty complex bit of logic. You can effectively get
trees of waiters, and it's possible to have tasks in the middle
of the tree be woken up. Then handling wakeups as they cascade
down the tree properly is also a bit complex, as there are extra
lists to manage the recursive style work without actually
recursing.
Hopefully the earlier patches will be easy to queue, but I
suspect there will be lots of review feedback for me to address
in the last two. :)
I’d love to get further feedback on any place where these patches
are confusing, or could use additional clarifications.
New in v31 of this set:
* Included Christian's patch to return early from
yield_task_dl() when we are proxying
* K Prateek's noticed a potential race where if a sleeping owner
is woken in parallel with the waiter enqueuing itself on the
sleeping owner, the waiting task could get stuck on that owner
until it sleeps and is woken up again. So a fix for this has
been made.
* Maria Yu and Tengfei Fan reported an issue with rq->nr_iowait
values getting out of balance, and provided a helpful
reproducer. I’ve adjusted the logic in
do_activate_blocked_waiter() to correct the imbalance.
* Included changes from Andrea Righi to adapt the sleeping owner
handling with his recent series to make sched_ext and
proxy-exec work together (his series and my series are fully
independent - I only have a two-line patch from Andrea that
will be needed if both changes land in parallel).
Additionally I’d appreciate any testing or comments that folks
have with the full Proxy Execution series! You can find the full
Proxy Exec series here:
https://github.com/johnstultz-work/linux-dev/commits/proxy-exec-v31-7.2-rc4
https://github.com/johnstultz-work/linux-dev.git proxy-exec-v31-7.2-rc4
In the full series, there's been quite a lot of exciting
changes, particularly three really interesting chunks of work
from Andrea, K Prateek and Suleiman!
New changes to the full patch series in this revision include:
* Included Andrea’s sched_ext changes to support sched_ext
with proxy-exec (along with a lot of pending sched_ext changes
his work is built on top of)!
* Included K Prateek’s deeper fixes to core-scheduling issues
with proxy-exec!
* Included first pass of Suleiman Souhlal’s efforts to get
proxy-enabled futexes working!
* Fixed a very subtle reported proxy-rwsems race with
rwsem_mark_wake(), which could cause the task::blocked_on
state checks to trip warnings, even when proxy-exec was
disabled.
* Updated test-ww_mutex patches from Håkon Bugge
Issues still to address with the full series:
* After the nr_wait imbalance was addressed, Maria Yu raised a
subtle difference in how the nr_iowait counting might be
attributed with proxy-exec: potentially proxy-migrated donors
that become blocked on sleeping owners could
increment/decrement the value on the owners cpu rq, instead of
on the donor’s original cpu rq. It’s unclear to me what the
impact of this would be, if at all, but it is potentially an
observable difference with proxy-exec, so I’m going to take a
swing at addressing it.
* Take a stab at lock-owner-count optimization idea from
K Prateek
* Reevaluate performance regression K Prateek Nayak found with
the full series earlier.
* The chain migration functionality needs further iterations and
better validation to ensure it truly maintains the RT/DL load
balancing invariants (despite this being broken in vanilla
upstream with RT_PUSH_IPI currently)
Future work:
* Expand to more locking primitives: Suleiman's draft work on
pi-futexes is ongoing, and using proxy for Binder PI is
something else we’re exploring.
* Eventually: Work to replace rt_mutexes and get things happy
with PREEMPT_RT
Credit/Disclaimer:
—--------------------
As always, this Proxy Execution series has a long history with
lots of developers that deserve credit:
First described in a paper[1] by Watkins, Straub, Niehaus, then
from patches from Peter Zijlstra, extended with lots of work by
Juri Lelli, Valentin Schneider, and Connor O'Brien. (and thank
you to Steven Rostedt for providing additional details here!).
Thanks also to Joel Fernandes, Dietmar Eggemann, Metin Kaya,
K Prateek Nayak, Suleiman Souhlal, Christian Loehle, and
Andrea Righi for their substantial review, suggestion, and patch
contributions.
So again, many thanks to those above, as all the credit for this
series really is due to them - while the mistakes are surely mine.
Thanks so much!
-john
[1] https://static.lwn.net/images/conf/rtlws11/papers/proc/p38.pdf
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
Andrea Righi (1):
sched: Distinguish proxy activations from wakeups
Christian Loehle (1):
sched/deadline: Ignore proxy-exec sched_yield()
John Stultz (4):
sched/core: Avoid migrating blocked_on tasks
sched: Switch rq->next_class in proxy_reset_donor()
sched: Break out core of attach_tasks() helper into sched.h
sched: Migrate whole chain in proxy_migrate_task()
Peter Zijlstra (1):
sched: Add deactivated (sleeping) owner handling to find_proxy_task()
Vasily Gorbik (2):
sched/core: Don't steal a proxy-exec donor
sched/core: Don't proxy-exec unmatched cookie lock owners
include/linux/sched.h | 7 +
init/init_task.c | 6 +
kernel/fork.c | 6 +
kernel/sched/core.c | 350 ++++++++++++++++++++++++++++++++++++----
kernel/sched/deadline.c | 3 +
kernel/sched/ext/ext.c | 8 +
kernel/sched/fair.c | 16 +-
kernel/sched/sched.h | 21 +++
8 files changed, 374 insertions(+), 43 deletions(-)
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v31 1/9] sched/deadline: Ignore proxy-exec sched_yield()
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 2/9] sched/core: Don't steal a proxy-exec donor John Stultz
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: Christian Loehle, Juri Lelli, John Stultz, Joel Fernandes,
Qais Yousef, Ingo Molnar, Peter Zijlstra, Vincent Guittot,
Dietmar Eggemann, Valentin Schneider, Steven Rostedt, Ben Segall,
Zimuzo Ezeozue, Will Deacon, Waiman Long, Boqun Feng,
Paul E. McKenney, Metin Kaya, Xuewen Yan, K Prateek Nayak,
Thomas Gleixner, Daniel Lezcano, Suleiman Souhlal, Andrea Righi,
kuyo chang, hupu, kernel-team
From: Christian Loehle <christian.loehle@arm.com>
With proxy execution, rq->curr is the execution context while rq->donor is
the donating context. rq->curr's sched_yield() is dispatched through
the donor class so that proxy execution follows the effective scheduling
context.
For SCHED_DEADLINE, this is too strong. yield_task_dl() does not just ask
for another task of equal priority to get to run, it marks the current DL
entity as yielded and forces it to sleep until replenishment. These
yield semantics are fundamentally different from FIFO/RR (where if no
equal-priority tasks are runnable, no harm done, they get picked again
immediately) or OTHER (also doesn't cause priority inversion), so do not
mix these semantics by ignoring a sched_yield() on DL donors.
Fixes: 127b90315ca0 ("sched/proxy: Yield the donor task")
Acked-by: Juri Lelli <juri.lelli@redhat.com>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: John Stultz <jstultz@google.com>
---
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
kernel/sched/deadline.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 0f858b98c9aa3..3e89b3abeb278 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -2574,6 +2574,9 @@ static bool dequeue_task_dl(struct rq *rq, struct task_struct *p, int flags)
*/
static void yield_task_dl(struct rq *rq)
{
+ if (sched_proxy_exec() && rq->curr != rq->donor)
+ return;
+
/*
* We make the task go to sleep until its current deadline by
* forcing its runtime to zero. This way, update_curr_dl() stops
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 2/9] sched/core: Don't steal a proxy-exec donor
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
2026-07-24 18:12 ` [PATCH v31 1/9] sched/deadline: Ignore proxy-exec sched_yield() John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 3/9] sched/core: Avoid migrating blocked_on tasks John Stultz
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: Vasily Gorbik, John Stultz, Joel Fernandes, Qais Yousef,
Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Valentin Schneider, Steven Rostedt, Ben Segall,
Zimuzo Ezeozue, Will Deacon, Waiman Long, Boqun Feng,
Paul E. McKenney, Metin Kaya, Xuewen Yan, K Prateek Nayak,
Thomas Gleixner, Daniel Lezcano, Suleiman Souhlal, Andrea Righi,
kuyo chang, hupu, kernel-team
From: Vasily Gorbik <gor@linux.ibm.com>
try_steal_cookie() avoids stealing src->core_pick and src->curr before
moving a task with the same cookie via move_queued_task_locked().
With proxy-exec, src->donor is the current scheduling context and may
differ from src->curr. Stealing it migrates a task that the source rq
still treats as current, leaving src's scheduler state for that task
stale. For CFS this means cfs_rq->curr points at the stolen entity,
and the next pick on the source rq hits the WARN_ON_ONCE in
put_prev_entity().
Commit 7de9d4f94638 ("sched: Start blocked_on chain processing in
find_proxy_task()") tweaked the fair class logic so that the donor task
isn't migrated away while we're running the proxy. Do it similarly for
try_steal_cookie() and skip src->donor as well.
Fixes: 7de9d4f94638 ("sched: Start blocked_on chain processing in find_proxy_task()")
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: John Stultz <jstultz@google.com>
---
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
kernel/sched/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 96226707c2f61..e7074ba54a91f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6474,7 +6474,7 @@ static bool try_steal_cookie(int this, int that)
return false;
do {
- if (p == src->core_pick || p == src->curr)
+ if (p == src->core_pick || p == src->curr || p == src->donor)
goto next;
if (!is_cpu_allowed(p, this))
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 3/9] sched/core: Avoid migrating blocked_on tasks
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
2026-07-24 18:12 ` [PATCH v31 1/9] sched/deadline: Ignore proxy-exec sched_yield() John Stultz
2026-07-24 18:12 ` [PATCH v31 2/9] sched/core: Don't steal a proxy-exec donor John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 4/9] sched/core: Don't proxy-exec unmatched cookie lock owners John Stultz
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: John Stultz, Joel Fernandes, Qais Yousef, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Valentin Schneider, Steven Rostedt, Ben Segall, Zimuzo Ezeozue,
Will Deacon, Waiman Long, Boqun Feng, Paul E. McKenney,
Metin Kaya, Xuewen Yan, K Prateek Nayak, Thomas Gleixner,
Daniel Lezcano, Suleiman Souhlal, Andrea Righi, kuyo chang, hupu,
kernel-team
Its not useful to migrate blocked_on tasks from other
runqueues as the proxy logic will just migrate it
back to the owner's rq. So skip blocked_on tasks here.
Signed-off-by: John Stultz <jstultz@google.com>
---
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
kernel/sched/core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e7074ba54a91f..8e661b5f133d7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6477,6 +6477,9 @@ static bool try_steal_cookie(int this, int that)
if (p == src->core_pick || p == src->curr || p == src->donor)
goto next;
+ if (task_is_blocked(p))
+ goto next;
+
if (!is_cpu_allowed(p, this))
goto next;
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 4/9] sched/core: Don't proxy-exec unmatched cookie lock owners
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
` (2 preceding siblings ...)
2026-07-24 18:12 ` [PATCH v31 3/9] sched/core: Avoid migrating blocked_on tasks John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 5/9] sched: Switch rq->next_class in proxy_reset_donor() John Stultz
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: Vasily Gorbik, K Prateek Nayak, John Stultz, Joel Fernandes,
Qais Yousef, Ingo Molnar, Peter Zijlstra, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Valentin Schneider,
Steven Rostedt, Ben Segall, Zimuzo Ezeozue, Will Deacon,
Waiman Long, Boqun Feng, Paul E. McKenney, Metin Kaya, Xuewen Yan,
Thomas Gleixner, Daniel Lezcano, Suleiman Souhlal, Andrea Righi,
kuyo chang, hupu, kernel-team
From: Vasily Gorbik <gor@linux.ibm.com>
Core scheduling chooses a core-wide cookie before __schedule()
installs the next task. With proxy-exec enabled, that task becomes the
donor/scheduling context, and find_proxy_task() may then replace the
execution context with the runnable mutex owner. If its cookie differs
from the selected core cookie, running it would bypass core scheduling's
cookie selection.
When the final mutex owner found by find_proxy_task() does not match the
selected core cookie, stop proxying the donor. If the current execution
context is already in the blocked chain, fall back to idle like the
existing proxy-exec retry paths do. Otherwise deactivate the donor and
let __schedule() pick again. The mutex owner can be picked later under
its own cookie.
Fixes: 7de9d4f94638 ("sched: Start blocked_on chain processing in find_proxy_task()")
Reported-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lore.kernel.org/lkml/10282ce9-f4ae-498f-9b57-f4e1e61fffbc@amd.com/
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
[jstultz: Added tweak to ensure we deactivate donor, not runnable owner]
Signed-off-by: John Stultz <jstultz@google.com>
---
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
kernel/sched/core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 8e661b5f133d7..36e1db67a8374 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7004,6 +7004,14 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf)
owner->blocked_donor = p;
}
WARN_ON_ONCE(owner && !owner->on_rq);
+
+ if (owner && !sched_cpu_cookie_match(rq, owner)) {
+ if (curr_in_chain)
+ return proxy_resched_idle(rq);
+ p = donor; /* Deactivate the donor, not the runnable owner */
+ clear_task_blocked_on(p, NULL);
+ goto deactivate;
+ }
return owner;
deactivate:
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 5/9] sched: Switch rq->next_class in proxy_reset_donor()
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
` (3 preceding siblings ...)
2026-07-24 18:12 ` [PATCH v31 4/9] sched/core: Don't proxy-exec unmatched cookie lock owners John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 6/9] sched: Break out core of attach_tasks() helper into sched.h John Stultz
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: John Stultz, Joel Fernandes, Qais Yousef, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Valentin Schneider, Steven Rostedt, Ben Segall, Zimuzo Ezeozue,
Will Deacon, Waiman Long, Boqun Feng, Paul E. McKenney,
Metin Kaya, Xuewen Yan, K Prateek Nayak, Thomas Gleixner,
Daniel Lezcano, Suleiman Souhlal, Andrea Righi, kuyo chang, hupu,
Vasily Gorbik, kernel-team
Similar to commit 04f80f8b12a0 ("sched: Switch rq->next_class on
proxy_resched_idle()"), we should also set the rq->next_class
when we call proxy_reset_donor().
Fixes: f13beb010e4a ("sched: Have try_to_wake_up() handle return-migration for PROXY_WAKING case")
Signed-off-by: John Stultz <jstultz@google.com>
---
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: kernel-team@android.com
---
kernel/sched/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 36e1db67a8374..564762ed36f2d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3750,6 +3750,7 @@ static inline void proxy_reset_donor(struct rq *rq)
WARN_ON_ONCE(rq->donor == rq->curr);
put_prev_set_next_task(rq, rq->donor, rq->curr);
+ rq->next_class = rq->curr->sched_class;
rq_set_donor(rq, rq->curr);
zap_balance_callbacks(rq);
resched_curr(rq);
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 6/9] sched: Break out core of attach_tasks() helper into sched.h
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
` (4 preceding siblings ...)
2026-07-24 18:12 ` [PATCH v31 5/9] sched: Switch rq->next_class in proxy_reset_donor() John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 7/9] sched: Migrate whole chain in proxy_migrate_task() John Stultz
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: John Stultz, K Prateek Nayak, Joel Fernandes, Qais Yousef,
Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Valentin Schneider, Steven Rostedt, Ben Segall,
Zimuzo Ezeozue, Will Deacon, Waiman Long, Boqun Feng,
Paul E. McKenney, Metin Kaya, Xuewen Yan, Thomas Gleixner,
Daniel Lezcano, Suleiman Souhlal, Andrea Righi, kuyo chang, hupu,
kernel-team
Pull the core of attach_tasks() out into sched.h so
it can be used more generically.
Suggested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Signed-off-by: John Stultz <jstultz@google.com>
---
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
kernel/sched/fair.c | 16 +---------------
kernel/sched/sched.h | 19 +++++++++++++++++++
2 files changed, 20 insertions(+), 15 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index d78467ec6ee13..6d2fa0cd77779 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -11035,21 +11035,7 @@ static int detach_tasks(struct lb_env *env)
*/
static void attach_tasks(struct lb_env *env)
{
- struct list_head *tasks = &env->tasks;
- struct task_struct *p;
- struct rq_flags rf;
-
- rq_lock(env->dst_rq, &rf);
- update_rq_clock(env->dst_rq);
-
- while (!list_empty(tasks)) {
- p = list_first_entry(tasks, struct task_struct, se.group_node);
- list_del_init(&p->se.group_node);
-
- attach_task(env->dst_rq, p);
- }
-
- rq_unlock(env->dst_rq, &rf);
+ __attach_tasks(env->dst_rq, &env->tasks);
}
#ifdef CONFIG_NO_HZ_COMMON
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 56acf502ba260..56d9c09c485e6 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -3100,6 +3100,25 @@ static inline void attach_one_task(struct rq *rq, struct task_struct *p)
attach_task(rq, p);
}
+/*
+ * __attach_tasks() - attaches a list of tasks (using se.group_node) to
+ * the new rq
+ */
+static inline void __attach_tasks(struct rq *rq, struct list_head *tasks)
+{
+ guard(rq_lock)(rq);
+ update_rq_clock(rq);
+
+ while (!list_empty(tasks)) {
+ struct task_struct *p;
+
+ p = list_first_entry(tasks, struct task_struct, se.group_node);
+ list_del_init(&p->se.group_node);
+
+ attach_task(rq, p);
+ }
+}
+
#ifdef CONFIG_PREEMPT_RT
# define SCHED_NR_MIGRATE_BREAK 8
#else
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 7/9] sched: Migrate whole chain in proxy_migrate_task()
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
` (5 preceding siblings ...)
2026-07-24 18:12 ` [PATCH v31 6/9] sched: Break out core of attach_tasks() helper into sched.h John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 8/9] sched: Add deactivated (sleeping) owner handling to find_proxy_task() John Stultz
2026-07-24 18:12 ` [PATCH v31 9/9] sched: Distinguish proxy activations from wakeups John Stultz
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: John Stultz, Joel Fernandes, Qais Yousef, Ingo Molnar,
Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann,
Valentin Schneider, Steven Rostedt, Ben Segall, Zimuzo Ezeozue,
Will Deacon, Waiman Long, Boqun Feng, Paul E. McKenney,
Metin Kaya, Xuewen Yan, K Prateek Nayak, Thomas Gleixner,
Daniel Lezcano, Suleiman Souhlal, Andrea Righi, kuyo chang, hupu,
kernel-team
Instead of migrating one task each time through find_proxy_task(),
we can walk up the blocked_donor ptrs and migrate the entire
current chain in one go.
This was broken out of earlier patches and held back while the
series was being stabilized, but I wanted to re-introduce it.
Signed-off-by: John Stultz <jstultz@google.com>
---
v12:
* Earlier this was re-using blocked_node, but I hit
a race with activating blocked entities, and to
avoid it introduced a new migration_node listhead
v18:
* Add init_task initialization of migration_node as suggested
by Suleiman
v22:
* Move migration_node under CONFIG_SCHED_PROXY_EXEC as suggested
by K Prateek
v25:
* Use se.group_node instead of adding migration_node, as
suggsested by K Prateek
* Integrated attach_tasks() cleanups suggested by K Prateek
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
kernel/sched/core.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 564762ed36f2d..1bf60d78c9208 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6819,9 +6819,9 @@ static void proxy_migrate_task(struct rq *rq, struct rq_flags *rf,
__must_hold(__rq_lockp(rq))
{
struct rq *target_rq = cpu_rq(target_cpu);
+ LIST_HEAD(migrate_list);
lockdep_assert_rq_held(rq);
- WARN_ON(p == rq->curr);
/*
* Since we are migrating a blocked donor, it could be rq->donor,
* and we want to make sure there aren't any references from this
@@ -6834,13 +6834,20 @@ static void proxy_migrate_task(struct rq *rq, struct rq_flags *rf,
* before we release the lock.
*/
proxy_resched_idle(rq);
-
- deactivate_task(rq, p, DEQUEUE_NOCLOCK);
- proxy_set_task_cpu(p, target_cpu);
-
+ for (; p; p = p->blocked_donor) {
+ WARN_ON(p == rq->curr);
+ deactivate_task(rq, p, DEQUEUE_NOCLOCK);
+ proxy_set_task_cpu(p, target_cpu);
+ /*
+ * We can re-use se.group_node to migrate the thing,
+ * because @p is deactivated (won't be balanced) and
+ * we hold the rq_lock.
+ */
+ list_add(&p->se.group_node, &migrate_list);
+ }
proxy_release_rq_lock(rq, rf);
- attach_one_task(target_rq, p);
+ __attach_tasks(target_rq, &migrate_list);
proxy_reacquire_rq_lock(rq, rf);
}
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 8/9] sched: Add deactivated (sleeping) owner handling to find_proxy_task()
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
` (6 preceding siblings ...)
2026-07-24 18:12 ` [PATCH v31 7/9] sched: Migrate whole chain in proxy_migrate_task() John Stultz
@ 2026-07-24 18:12 ` John Stultz
2026-07-24 18:12 ` [PATCH v31 9/9] sched: Distinguish proxy activations from wakeups John Stultz
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: Peter Zijlstra, Juri Lelli, Valentin Schneider,
Connor O'Brien, John Stultz, Joel Fernandes, Qais Yousef,
Ingo Molnar, Vincent Guittot, Dietmar Eggemann,
Valentin Schneider, Steven Rostedt, Ben Segall, Zimuzo Ezeozue,
Mel Gorman, Will Deacon, Waiman Long, Boqun Feng,
Paul E. McKenney, Metin Kaya, Xuewen Yan, K Prateek Nayak,
Thomas Gleixner, Daniel Lezcano, Suleiman Souhlal, Andrea Righi,
kuyo chang, hupu, kernel-team
From: Peter Zijlstra <peterz@infradead.org>
If the blocked_on chain resolves to a sleeping owner, deactivate
the donor task, and enqueue it on the sleeping owner task.
Then re-activate it later when the owner is woken up.
NOTE: This has been particularly challenging to get working
properly, and some of the locking is particularly awkward. I'd
very much appreciate review and feedback for ways to simplify
this.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Juri Lelli <juri.lelli@redhat.com>
Signed-off-by: Valentin Schneider <valentin.schneider@arm.com>
Signed-off-by: Connor O'Brien <connoro@google.com>
[jstultz: This was broken out from the larger proxy() patch]
Signed-off-by: John Stultz <jstultz@google.com>
---
v5:
* Split out from larger proxy patch
v6:
* Major rework, replacing the single list head per task with
per-task list head and nodes, creating a tree structure so
we only wake up descendants of the task woken.
* Reworked the locking to take the task->pi_lock, so we can
avoid mid-chain wakeup races from try_to_wake_up() called by
the ww_mutex logic.
v7:
* Drop unnecessary __nested lock annotation, as we already drop
the lock prior.
* Add comments on #else & #endif lines, and clearer function
names, and commit message tweaks as suggested by Metin Kaya
* Move activate_blocked_entities() call from ttwu_queue to
try_to_wake_up() to simplify locking. Thanks to questions from
Metin Kaya
* Fix irqsave/irqrestore usage now we call this outside where
the pi_lock is held
* Fix activate_blocked_entitites not preserving wake_cpu
* Fix for UP builds
v8:
* Minor checkpatch fixup
* Drop proxy_deactivate and cleanups suggested by Metin
v9:
* Fix bug causing possibly uninitialized cpu value to be used with
activate_blocked_entities()
* Improved comment around preserving wake_cpu suggested by Metin
* Add additional lockdep asserts, suggested by Metin
* Tweaked placement of lockdep assert, suggested by Metin
* Fixed comment referring to structure entry name
* Fix to call proxy_resched_idle() _prior_ to calling
proxy_enqueue_on_owner() where we deactivate the task, this
avoids stale references to rq_selected() when the task may
have been migrated to another rq.
* Fix to remove the blocked_head list at the start of
activate_blocked_entities() so we only do a finite amount
of work, avoiding a potential livelock of two cpus removing
and adding tasks to the list at the same time if the owner
went back to sleep while blocked entities were being woken.
v11:
* Big rework to get rid of recursion. Had to add another list
item to the task_stuct to do this as we are in atomic context
and cannot allocate memory while activating blocked entities.
Will need to watch carefully for bugs, as switching to a
list_head in the task_struct instead of a pointer on the
stack opens up the potential for races on the shared state,
but I think I've got the locking sorted.
* Moved proxy_set_task_cpu helper to earlier in the series
* Minor rework for try_to_deactivate_task changes
* Minor variable name cleanups suggested by Metin
v13:
* Switch to use donor from next for proxy_enqueue_on_owner
* Switch to using block_task instead of deactivate_task
v14:
* Ensure we call block_task() last in proxy_enqueue_on_owner
and not touch it again to avoid races where it might be
activated on another cpu
* Make sure we activate blocked_entities when we exit from ttwu
* Fix to enqueue the last task in the chain (p) on the blocked
owner instead of donor, so that we preserve the chain
structure so mid-chain wakeups propagate properly
* Rework of sleeping_owner handling so that we properly deal
with delayed-dequeued (sched_delayed) tasks (also removes
now unused proxy_deactivate() logic)
v15:
* Rework do_activate_task to be activate_task() and have it
call __activate_task(), suggested by Carlos Llamas
* Put task_struct additions under CONFIG_SCHED_PROXY_EXEC
v16:
* Rework do_activate_blocked_waiter locking to use scoped_guard
* Rework find_proxy_task() logic to use guard
v18:
* Integrate Suleiman's suggested optimization to check sleeping
owner status before task_cpu, to avoid unnecssarily
proxy-migrating tasks to then just dequeue them.
* Add on_cpu check to fix for a very hard to reproduce race where
a late blocked_task_activation() happens while the task is already
on_cpu elsewhere. When we get to __schedule() we block the task
(!on_rq) but haven't yet switched away. blocked_task_activation()
would then incorrectly activate on a different runqueue.
* Add init_task initialization for sleeping owner lists, as
suggested by Suleiman
v19:
* Build fixup for !CONFIG_SMP
v22:
* Rework to avoid gotos in guard() scopes, using break and
switch() on action values. Suggested by K Prateek.
v25:
* Fix elevated nr_uninterruptible and nr_iowait counts,
which were causing bad loadavg values. Reported and
fixed by David Stevens <stevensd@google.com>
v28:
* In __proxy_remove_from_sleeping_owner() we call
put_task(), which might free the owner while we are
still holing the owners->blocked_lock. So be sure
to get_task()/put_task() around the owner usage to
ensure we don't prematurely free the task.
* Also reorder the put_task/unlock lines in
activate_blocked_waiters(), to avoid a similar issue
v30:
* Optimize activate_blocked_waiters() so we don't do so much
unnecessary work when proxy-exec is enabled. If there are
no blocked waiters, we can return early.
v31:
* K Prateek's noticed a potential race where if a sleeping owner
is woken in paralell with the waiter enquing itself on the
sleeping owner, the waiting task could get stuck on that owner
until it sleeps and is woken up again. So double check after
we grab the blocked_lock to avoid this.
* Maria Yu and Tengfei Fan reported an issue with rq->nr_iowait
values getting out of balance, and provided a helpful
reproducer. To fix this, make sure we do the atomic_dec() in
do_activate_blocked_waiter() before we call
proxy_set_task_cpu() so we always dec on the same rq we
inc'ed.
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
include/linux/sched.h | 7 +
init/init_task.c | 6 +
kernel/fork.c | 6 +
kernel/sched/core.c | 317 +++++++++++++++++++++++++++++++++++++++---
4 files changed, 315 insertions(+), 21 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 373bcc0598d10..8c2ba6dce58f4 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1251,6 +1251,13 @@ struct task_struct {
struct mutex *blocked_on; /* lock we're blocked on */
raw_spinlock_t blocked_lock;
+#ifdef CONFIG_SCHED_PROXY_EXEC
+ struct list_head blocked_head; /* tasks blocked on this task */
+ struct list_head blocked_node; /* our entry on someone elses blocked_head */
+ /* Node for list of tasks to process blocked_head list for blocked entitiy activations */
+ struct list_head blocked_activation_node;
+ struct task_struct *sleeping_owner; /* task our blocked_node is enqueued on */
+#endif
/*
* The task that is boosting this task; a back link for the current
diff --git a/init/init_task.c b/init/init_task.c
index b67ef6040a655..809282a2741d7 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -211,6 +211,12 @@ struct task_struct init_task __aligned(L1_CACHE_BYTES) = {
&init_task.alloc_lock),
#endif
.blocked_donor = NULL,
+#ifdef CONFIG_SCHED_PROXY_EXEC
+ .blocked_head = LIST_HEAD_INIT(init_task.blocked_head),
+ .blocked_node = LIST_HEAD_INIT(init_task.blocked_node),
+ .blocked_activation_node = LIST_HEAD_INIT(init_task.blocked_activation_node),
+ .sleeping_owner = NULL,
+#endif
#ifdef CONFIG_RT_MUTEXES
.pi_waiters = RB_ROOT_CACHED,
.pi_top_task = NULL,
diff --git a/kernel/fork.c b/kernel/fork.c
index f0e2e131a9a5a..6dfde115fe34e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2247,6 +2247,12 @@ __latent_entropy struct task_struct *copy_process(
p->blocked_on = NULL; /* not blocked yet */
p->blocked_donor = NULL; /* nobody is boosting p yet */
+#ifdef CONFIG_SCHED_PROXY_EXEC
+ INIT_LIST_HEAD(&p->blocked_head);
+ INIT_LIST_HEAD(&p->blocked_node);
+ INIT_LIST_HEAD(&p->blocked_activation_node);
+ p->sleeping_owner = NULL;
+#endif
#ifdef CONFIG_BCACHE
p->sequential_io = 0;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 1bf60d78c9208..d813a9c2f0c35 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2216,7 +2216,7 @@ inline bool dequeue_task(struct rq *rq, struct task_struct *p, int flags)
return p->sched_class->dequeue_task(rq, p, flags);
}
-void activate_task(struct rq *rq, struct task_struct *p, int flags)
+static inline void __activate_task(struct rq *rq, struct task_struct *p, int flags)
{
if (task_on_rq_migrating(p))
flags |= ENQUEUE_MIGRATED;
@@ -2227,6 +2227,71 @@ void activate_task(struct rq *rq, struct task_struct *p, int flags)
ASSERT_EXCLUSIVE_WRITER(p->on_rq);
}
+#ifdef CONFIG_SCHED_PROXY_EXEC
+static inline
+void __proxy_remove_from_sleeping_owner(struct task_struct *owner, struct task_struct *p)
+{
+ lockdep_assert_held(&owner->blocked_lock);
+
+ if (p->sleeping_owner == owner) {
+ list_del_init(&p->blocked_node);
+ WRITE_ONCE(p->sleeping_owner, NULL);
+ put_task_struct(owner); // matches get in proxy_enqueue_on_owner
+ }
+}
+
+static inline void proxy_remove_from_sleeping_owner(struct task_struct *p)
+{
+ struct task_struct *owner = READ_ONCE(p->sleeping_owner);
+
+ if (owner) {
+ /*
+ * __proxy_remove_from_sleeping_owner() does a
+ * put on owner to match the get done in
+ * proxy_enqueue_on_owner(). If that put is the
+ * last one and it frees owner, we'd be freeing
+ * a lock we held. So get/put owner around its
+ * usage her to ensure that doesn't happen.
+ */
+ get_task_struct(owner);
+ raw_spin_lock(&owner->blocked_lock);
+ __proxy_remove_from_sleeping_owner(owner, p);
+ raw_spin_unlock(&owner->blocked_lock);
+ put_task_struct(owner);
+ }
+}
+
+void activate_task(struct rq *rq, struct task_struct *p, int en_flags)
+{
+ if (!sched_proxy_exec()) {
+ __activate_task(rq, p, en_flags);
+ return;
+ }
+
+ lockdep_assert_rq_held(rq);
+ proxy_remove_from_sleeping_owner(p);
+ /*
+ * By calling __activate_task() with blocked_lock held, we
+ * order against the find_proxy_task() blocked_task case
+ * such that no more blocked tasks will be enqueued on p
+ * once we release p->blocked_lock.
+ */
+ raw_spin_lock(&p->blocked_lock);
+ WARN_ON(task_cpu(p) != cpu_of(rq));
+ __activate_task(rq, p, en_flags);
+ raw_spin_unlock(&p->blocked_lock);
+}
+#else
+static inline void proxy_remove_from_sleeping_owner(struct task_struct *p)
+{
+}
+
+void activate_task(struct rq *rq, struct task_struct *p, int en_flags)
+{
+ __activate_task(rq, p, en_flags);
+}
+#endif
+
void deactivate_task(struct rq *rq, struct task_struct *p, int flags)
{
WARN_ON_ONCE(flags & DEQUEUE_SLEEP);
@@ -3756,6 +3821,169 @@ static inline void proxy_reset_donor(struct rq *rq)
resched_curr(rq);
}
+static inline void proxy_set_task_cpu(struct task_struct *p, int cpu)
+{
+ unsigned int wake_cpu;
+
+ /*
+ * Since we are enqueuing a blocked task on a cpu it may
+ * not be able to run on, preserve wake_cpu when we
+ * __set_task_cpu so we can return the task to where it
+ * was previously runnable.
+ */
+ wake_cpu = p->wake_cpu;
+ __set_task_cpu(p, cpu);
+ p->wake_cpu = wake_cpu;
+}
+
+static void do_activate_blocked_waiter(struct rq *target_rq, struct task_struct *p, int en_flags)
+{
+ unsigned int state;
+ struct rq_flags rf;
+ int target_cpu = cpu_of(target_rq);
+
+ scoped_guard (raw_spinlock_irqsave, &p->pi_lock) {
+ state = READ_ONCE(p->__state);
+ /* Avoid racing with ttwu */
+ if (state == TASK_WAKING)
+ return;
+
+ if (READ_ONCE(p->on_rq)) {
+ /*
+ * We raced with a non mutex handoff activation of p.
+ * That activation will also take care of activating
+ * all of the tasks after p in the blocked_head list,
+ * so we're done here.
+ */
+ return;
+ }
+ if (task_on_cpu(task_rq(p), p)) {
+ /*
+ * Its possible this activation is very late, and
+ * we already were woken up and are running on a
+ * different cpu. If that task blocked, it could be
+ * dequeued (so on_rq == 0), but still on_cpu.
+ * Bail in this case, as we definitely don't want to
+ * activate a task when its on_cpu elsewhere.
+ */
+ return;
+ }
+ /*
+ * Have to make sure we handle nr_iowait adjustment before
+ * we call proxy_set_task_cpu() to ensure we are adjusting
+ * the same runqueue we left (where block_task()
+ * incremented nr_iowait).
+ */
+ if (p->in_iowait) {
+ delayacct_blkio_end(p);
+ atomic_dec(&task_rq(p)->nr_iowait);
+ }
+ proxy_set_task_cpu(p, target_cpu);
+ rq_lock_irqsave(target_rq, &rf);
+ /*
+ * proxy_enqueue_on_owner() called block_task() which
+ * increments nr_uninterruptible, so we need to reverse
+ * that when we activate the blocked waiter
+ */
+ if (p->sched_contributes_to_load)
+ target_rq->nr_uninterruptible--;
+ update_rq_clock(target_rq);
+ activate_task(target_rq, p, en_flags);
+ resched_curr(target_rq);
+ rq_unlock_irqrestore(target_rq, &rf);
+ }
+}
+
+static void activate_blocked_waiters(struct rq *target_rq,
+ struct task_struct *owner,
+ int wake_flags)
+{
+ struct list_head bal_head;
+ unsigned long flags;
+ int en_flags = ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK;
+
+ if (!sched_proxy_exec())
+ return;
+
+ /*
+ * A whole bunch of waiting donor tasks back this blocked
+ * lock owner task, wake them all up to give this task its
+ * 'fair' share.
+ *
+ * This is a little unique here and the locking is messy.
+ * At this point we only hold the blocked_lock, so the
+ * owner task may be able to run and do all sorts of
+ * things while we are processing the blocked_head list,
+ * including going back to sleep, which can cause tasks
+ * to be added to the owners->blocked_head while we are
+ * processing it!
+ * Thus, we pull the entire list off the owner->blocked_head
+ * here so that we will only process a finite amount of
+ * tasks. Tasks added after this will be processed by the
+ * future wake events.
+ * Even though we have pulled the list off the blocked_head
+ * the removed list is *still* "owned" and serialized by
+ * the owner->blocked_lock! As we have to serialize against
+ * mid-chain wakeups, who may try to remove themselves from
+ * the list.
+ */
+ raw_spin_lock_irqsave(&owner->blocked_lock, flags);
+ if (!list_empty(&owner->blocked_activation_node)) {
+ raw_spin_unlock_irqrestore(&owner->blocked_lock, flags);
+ return;
+ }
+
+ if (list_empty(&owner->blocked_head)) {
+ raw_spin_unlock_irqrestore(&owner->blocked_lock, flags);
+ return;
+ }
+
+ get_task_struct(owner);
+ INIT_LIST_HEAD(&bal_head);
+ list_add_tail(&owner->blocked_activation_node, &bal_head);
+ raw_spin_unlock_irqrestore(&owner->blocked_lock, flags);
+
+ if (wake_flags & WF_MIGRATED)
+ en_flags |= ENQUEUE_MIGRATED;
+
+ while (!list_empty(&bal_head)) {
+ struct list_head tmp_head;
+
+ INIT_LIST_HEAD(&tmp_head);
+ owner = list_first_entry(&bal_head, struct task_struct, blocked_activation_node);
+
+ raw_spin_lock_irqsave(&owner->blocked_lock, flags);
+ list_replace_init(&owner->blocked_head, &tmp_head);
+ list_del_init(&owner->blocked_activation_node);
+ while (!list_empty(&tmp_head)) {
+ struct task_struct *p;
+
+ p = list_first_entry(&tmp_head,
+ struct task_struct,
+ blocked_node);
+ WARN_ON(p == owner);
+ WARN_ON(p->sleeping_owner != owner);
+ __proxy_remove_from_sleeping_owner(owner, p);
+ raw_spin_unlock_irqrestore(&owner->blocked_lock, flags);
+
+ do_activate_blocked_waiter(target_rq, p, en_flags);
+
+ raw_spin_lock_irqsave(&p->blocked_lock, flags);
+ if (list_empty(&p->blocked_activation_node)) {
+ get_task_struct(p);
+ list_add_tail(&p->blocked_activation_node, &bal_head);
+ }
+ raw_spin_unlock_irqrestore(&p->blocked_lock, flags);
+
+ raw_spin_lock_irqsave(&owner->blocked_lock, flags);
+ }
+ raw_spin_unlock_irqrestore(&owner->blocked_lock, flags);
+ put_task_struct(owner); // put matches get prior to adding to local bal_head
+ }
+}
+
+static inline struct task_struct *proxy_resched_idle(struct rq *rq);
+
/*
* Checks to see if task p has been proxy-migrated to another rq
* and needs to be returned. If so, we deactivate the task here
@@ -3800,6 +4028,10 @@ static inline bool proxy_needs_return(struct rq *rq, struct task_struct *p)
{
return false;
}
+
+static inline void activate_blocked_waiters(struct rq *target_rq,
+ struct task_struct *owner,
+ int wake_flags) {}
#endif /* CONFIG_SCHED_PROXY_EXEC */
static void
@@ -3873,8 +4105,10 @@ static int ttwu_runnable(struct task_struct *p, int wake_flags)
update_rq_clock(rq);
if (p->is_blocked) {
- if (p->se.sched_delayed)
+ if (p->se.sched_delayed) {
+ proxy_remove_from_sleeping_owner(p);
enqueue_task(rq, p, ENQUEUE_NOCLOCK | ENQUEUE_DELAYED);
+ }
if (proxy_needs_return(rq, p))
return 0;
}
@@ -3903,13 +4137,19 @@ void sched_ttwu_pending(void *arg)
update_rq_clock(rq);
llist_for_each_entry_safe(p, t, llist, wake_entry.llist) {
+ int wake_flags;
if (WARN_ON_ONCE(p->on_cpu))
smp_cond_load_acquire(&p->on_cpu, !VAL);
if (WARN_ON_ONCE(task_cpu(p) != cpu_of(rq)))
set_task_cpu(p, cpu_of(rq));
- ttwu_do_activate(rq, p, p->sched_remote_wakeup ? WF_MIGRATED : 0, &rf);
+ wake_flags = p->sched_remote_wakeup ? WF_MIGRATED : 0;
+ ttwu_do_activate(rq, p, wake_flags, &rf);
+ rq_unlock(rq, &rf);
+ activate_blocked_waiters(rq, p, wake_flags);
+ rq_lock(rq, &rf);
+ update_rq_clock(rq);
}
/*
@@ -4416,6 +4656,7 @@ int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
ttwu_queue(p, cpu, wake_flags);
}
out:
+ activate_blocked_waiters(cpu_rq(task_cpu(p)), p, wake_flags);
if (success)
ttwu_stat(p, task_cpu(p), wake_flags);
@@ -6731,21 +6972,6 @@ static bool try_to_block_task(struct rq *rq, struct task_struct *p,
}
#ifdef CONFIG_SCHED_PROXY_EXEC
-static inline void proxy_set_task_cpu(struct task_struct *p, int cpu)
-{
- unsigned int wake_cpu;
-
- /*
- * Since we are enqueuing a blocked task on a cpu it may
- * not be able to run on, preserve wake_cpu when we
- * __set_task_cpu so we can return the task to where it
- * was previously runnable.
- */
- wake_cpu = p->wake_cpu;
- __set_task_cpu(p, cpu);
- p->wake_cpu = wake_cpu;
-}
-
static inline struct task_struct *proxy_resched_idle(struct rq *rq)
{
put_prev_set_next_task(rq, rq->donor, rq->idle);
@@ -6852,6 +7078,29 @@ static void proxy_migrate_task(struct rq *rq, struct rq_flags *rf,
proxy_reacquire_rq_lock(rq, rf);
}
+static void proxy_enqueue_on_owner(struct rq *rq, struct task_struct *owner,
+ struct task_struct *p)
+{
+ lockdep_assert_rq_held(rq);
+ lockdep_assert_held(&owner->blocked_lock);
+ /*
+ * ttwu_activate() will pick them up and place them on whatever rq
+ * @owner will run next.
+ */
+ WARN_ON(p == owner);
+ WARN_ON(!p->on_rq);
+ WARN_ON(p->sleeping_owner);
+ get_task_struct(owner);
+ WRITE_ONCE(p->sleeping_owner, owner);
+ /*
+ * ttwu_do_activate must not have a chance to activate p
+ * elsewhere before it's fully extricated from its old rq.
+ */
+ list_add(&p->blocked_node, &owner->blocked_head);
+ proxy_resched_idle(rq);
+ block_task(rq, p, READ_ONCE(p->__state));
+}
+
/*
* Find runnable lock owner to proxy for mutex blocked donor
*
@@ -6938,11 +7187,37 @@ 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 */
+ /*
+ * rq->curr must not be added to the blocked_head list or else
+ * ttwu_do_activate could enqueue it elsewhere before it switches
+ * out here. The approach to avoid this is the same as in the
+ * migrate_task case.
+ */
if (curr_in_chain)
return proxy_resched_idle(rq);
- __clear_task_blocked_on(p, NULL);
- goto deactivate;
+ /*
+ * If !@owner->on_rq, holding @rq->lock will not pin the task,
+ * so we cannot drop @mutex->wait_lock until we're sure its a blocked
+ * task on this rq.
+ *
+ * We use @owner->blocked_lock to serialize against ttwu_activate().
+ * Either we see its new owner->on_rq or it will see our list_add().
+ */
+ WARN_ON(owner == p);
+ raw_spin_unlock(&p->blocked_lock);
+ raw_spin_lock(&owner->blocked_lock);
+ /*
+ * Before actually adding to the sleeping owner, double check
+ * we didn't race with an owner wakeup before grabbing the
+ * owner's blocked_lock.
+ */
+ if (!READ_ONCE(owner->on_rq) || owner->se.sched_delayed)
+ proxy_enqueue_on_owner(rq, owner, p);
+
+ raw_spin_unlock(&owner->blocked_lock);
+ raw_spin_lock(&p->blocked_lock);
+
+ return NULL; /* retry task selection */
}
owner_cpu = task_cpu(owner);
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v31 9/9] sched: Distinguish proxy activations from wakeups
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
` (7 preceding siblings ...)
2026-07-24 18:12 ` [PATCH v31 8/9] sched: Add deactivated (sleeping) owner handling to find_proxy_task() John Stultz
@ 2026-07-24 18:12 ` John Stultz
8 siblings, 0 replies; 10+ messages in thread
From: John Stultz @ 2026-07-24 18:12 UTC (permalink / raw)
To: LKML
Cc: Andrea Righi, John Stultz, Joel Fernandes, Qais Yousef,
Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Valentin Schneider, Steven Rostedt, Ben Segall,
Zimuzo Ezeozue, Mel Gorman, Will Deacon, Waiman Long, Boqun Feng,
Paul E. McKenney, Metin Kaya, Xuewen Yan, K Prateek Nayak,
Thomas Gleixner, Daniel Lezcano, Suleiman Souhlal, kuyo chang,
hupu, kernel-team
From: Andrea Righi <arighi@nvidia.com>
Sleeping-owner handling reactivates blocked waiters with wakeup enqueue
semantics so scheduling classes can restore their runnable accounting.
Unlike a normal wakeup, the waiter remains blocked and is only made
runnable to donate its scheduling context.
Add ENQUEUE_PROXY to identify this activation and set it alongside
ENQUEUE_WAKEUP. Consume the internal marker in sched_ext and suppress
SCX_ENQ_WAKEUP before invoking BPF so the activation can be handled as
a blocked proxy donor.
Signed-off-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: John Stultz <jstultz@google.com>
---
Cc: Joel Fernandes <joelagnelf@nvidia.com>
Cc: Qais Yousef <qyousef@layalina.io>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ben Segall <bsegall@google.com>
Cc: Zimuzo Ezeozue <zezeozue@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Will Deacon <will@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Metin Kaya <Metin.Kaya@arm.com>
Cc: Xuewen Yan <xuewen.yan94@gmail.com>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Suleiman Souhlal <suleiman@google.com>
Cc: Andrea Righi <arighi@nvidia.com>
Cc: kuyo chang <kuyo.chang@mediatek.com>
Cc: hupu <hupu.gm@gmail.com>
Cc: kernel-team@android.com
---
kernel/sched/core.c | 2 +-
kernel/sched/ext/ext.c | 8 ++++++++
kernel/sched/sched.h | 2 ++
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d813a9c2f0c35..c54e9fedc9cd8 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3900,7 +3900,7 @@ static void activate_blocked_waiters(struct rq *target_rq,
{
struct list_head bal_head;
unsigned long flags;
- int en_flags = ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK;
+ int en_flags = ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK | ENQUEUE_PROXY;
if (!sched_proxy_exec())
return;
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index e3fa7b2fac9df..834c8b6dae6c9 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -2021,6 +2021,14 @@ static void enqueue_task_scx(struct rq *rq, struct task_struct *p, int core_enq_
int sticky_cpu = p->scx.sticky_cpu;
u64 enq_flags = core_enq_flags | rq->scx.extra_enq_flags;
+ /*
+ * Sleeping-owner activation uses wakeup semantics for the core
+ * scheduling classes, but the donor remains blocked. Expose it to BPF
+ * as a blocked-donor admission rather than a full wakeup.
+ */
+ if (core_enq_flags & ENQUEUE_PROXY)
+ enq_flags &= ~(ENQUEUE_PROXY | SCX_ENQ_WAKEUP);
+
if (enq_flags & ENQUEUE_WAKEUP)
rq->scx.flags |= SCX_RQ_IN_WAKEUP;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 56d9c09c485e6..e38988574cfa2 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2540,6 +2540,7 @@ extern const u32 sched_prio_to_wmult[40];
* ENQUEUE_REPLENISH - CBS (replenish runtime and postpone deadline)
* ENQUEUE_MIGRATED - the task was migrated during wakeup
* ENQUEUE_RQ_SELECTED - ->select_task_rq() was called
+ * ENQUEUE_PROXY - activate a blocked donor behind a waking owner
*
* XXX SAVE/RESTORE in combination with CLASS doesn't really make sense, but
* SCHED_DEADLINE seems to rely on this for now.
@@ -2571,6 +2572,7 @@ extern const u32 sched_prio_to_wmult[40];
#define ENQUEUE_MIGRATED 0x00040000
#define ENQUEUE_INITIAL 0x00080000
#define ENQUEUE_RQ_SELECTED 0x00100000
+#define ENQUEUE_PROXY 0x00200000
#define RETRY_TASK ((void *)-1UL)
--
2.55.0.229.g6434b31f56-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-07-24 18:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-24 18:12 [PATCH v31 0/9] Sleeping Owner Handling for Proxy Execution (v31) John Stultz
2026-07-24 18:12 ` [PATCH v31 1/9] sched/deadline: Ignore proxy-exec sched_yield() John Stultz
2026-07-24 18:12 ` [PATCH v31 2/9] sched/core: Don't steal a proxy-exec donor John Stultz
2026-07-24 18:12 ` [PATCH v31 3/9] sched/core: Avoid migrating blocked_on tasks John Stultz
2026-07-24 18:12 ` [PATCH v31 4/9] sched/core: Don't proxy-exec unmatched cookie lock owners John Stultz
2026-07-24 18:12 ` [PATCH v31 5/9] sched: Switch rq->next_class in proxy_reset_donor() John Stultz
2026-07-24 18:12 ` [PATCH v31 6/9] sched: Break out core of attach_tasks() helper into sched.h John Stultz
2026-07-24 18:12 ` [PATCH v31 7/9] sched: Migrate whole chain in proxy_migrate_task() John Stultz
2026-07-24 18:12 ` [PATCH v31 8/9] sched: Add deactivated (sleeping) owner handling to find_proxy_task() John Stultz
2026-07-24 18:12 ` [PATCH v31 9/9] sched: Distinguish proxy activations from wakeups John Stultz
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.