[PATCH] sched/core: fix task_sched_runtime() for proxy execution

From: Hui Su

Date: Wed Sep 02 2026 - 07:34:35 EST


With proxy execution, rq->donor is the scheduling context while
rq->curr is the execution context. Runtime accounting charges
sum_exec_runtime to rq->curr, while scheduler-side accounting is
charged to rq->donor.

task_sched_runtime() currently flushes pending runtime only when the
queried task is rq->donor. As a result, when a mutex owner is being
proxy-executed, it is rq->curr but not rq->donor, and its pending
sum_exec_runtime is not flushed before being returned. CPUCLOCK_SCHED
reads can therefore observe stale runtime until the next scheduler
accounting event.

Check whether the queried task is the current execution context instead.
The update itself must still be performed through rq->donor->sched_class,
as the scheduling state belongs to the donor. This is particularly
important when the donor and execution context belong to different
scheduling classes.

When rq->donor == rq->curr, the behavior is unchanged.

Tested with both RT and fair donors proxy-executing a fair mutex owner.
Before the change, CPUCLOCK_SCHED reads repeatedly returned unchanged
runtime during confirmed proxy-execution windows. After the change, no
stale reads were observed. The non-proxy control case was unchanged.

Fixes: 7de9d4f94638 ("sched: Start blocked_on chain processing in find_proxy_task()")
Signed-off-by: Hui Su <sh_def@xxxxxxx>
---
kernel/sched/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index f78275192036..83a82a4d1087 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5706,10 +5706,10 @@ unsigned long long task_sched_runtime(struct task_struct *p)
* project cycles that may never be accounted to this
* thread, breaking clock_gettime().
*/
- if (task_current_donor(rq, p) && task_on_rq_queued(p)) {
+ if (task_current(rq, p) && task_on_rq_queued(p)) {
prefetch_curr_exec_start(p);
update_rq_clock(rq);
- p->sched_class->update_curr(rq);
+ rq->donor->sched_class->update_curr(rq);
}
ns = p->se.sum_exec_runtime;
task_rq_unlock(rq, p, &rf);
--
2.54.0