* [PATCH v2] sched/core: Use the scheduling context for remote ticks
@ 2026-10-21 17:15 Shubhang Kaushik (Ampere)
2026-10-21 20:09 ` John Stultz
0 siblings, 1 reply; 3+ messages in thread
From: Shubhang Kaushik (Ampere) @ 2026-10-21 17:15 UTC (permalink / raw)
To: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
Valentin Schneider, K Prateek Nayak, Connor O'Brien,
John Stultz, Shubhang Kaushik, Christoph Lameter (Ampere)
Cc: linux-kernel, Shubhang Kaushik (Ampere)
sched_tick_remote() invokes task_tick() for rq->curr. With proxy
execution, rq->curr is the mutex-owner execution context while
rq->donor is the blocked task that supplies the scheduling context.
A mutex-blocked task remains queued for proxy execution. If that task
is SCHED_FIFO, or the only SCHED_RR task, sched_can_stop_tick() permits
the full-nohz tick to stop. find_proxy_task() can then select its mutex
owner as rq->curr while retaining the blocked task as rq->donor.
sched_tick() and hrtick() already invoke task_tick() for rq->donor.
Like task_tick(), the remote tick's full-nohz interval sanity check
currently uses rq->curr. The proxy owner in rq->curr can have a stale
se.exec_start before the accounting path updates it.
Make sched_tick_remote() use rq->donor for both the class tick and the
full-nohz tick-interval sanity check.
Fixes: 7de9d4f94638 ("sched: Start blocked_on chain processing in find_proxy_task()")
Signed-off-by: Shubhang Kaushik (Ampere) <sh@gentwo.org>
---
Testing was performed on an Ampere Altra system with
CONFIG_SCHED_PROXY_EXEC=y and CONFIG_NO_HZ_FULL=y, booted with:
sched_proxy_exec=1 nohz_full=78
On the unpatched baseline, 70dd4ee72eb2 (7.3.0-rc7), mutex locktorture
with four writers pinned to CPU 78 and RT boosting triggered:
WARNING: kernel/sched/core.c:5895 at sched_tick_remote...
Workqueue: events_unbound sched_tick_remote
This warning is WARN_ON_ONCE(rq->curr != rq->donor), demonstrating that
a full-nohz remote tick can run while the executing task and scheduling
context differ.
The v2 patched kernel completed the same 10 minute workload
without scheduler warnings or locktorture failures.
Changes in v2:
- Use rq->donor for the full-nohz tick-interval sanity check.
- Drop the redundant proxy-execution code comment.
Link to v1: https://lore.kernel.org/r/20261016-remote-tick-proxy-v1-1-272757a50a07@gentwo.org
---
kernel/sched/core.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 0ab15f03cb947eb958ff9f97d890716346377889..729ebaca35e1a9a12cda59e96c650ee6b1576951 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5934,26 +5934,20 @@ static void sched_tick_remote(struct work_struct *work)
*/
if (tick_nohz_tick_stopped_cpu(cpu)) {
guard(rq_lock_irq)(rq);
- struct task_struct *curr = rq->curr;
+ struct task_struct *donor = rq->donor;
if (cpu_online(cpu)) {
- /*
- * Since this is a remote tick for full dynticks mode,
- * we are always sure that there is no proxy (only a
- * single task is running).
- */
- WARN_ON_ONCE(rq->curr != rq->donor);
update_rq_clock(rq);
- if (!is_idle_task(curr)) {
+ if (!is_idle_task(donor)) {
/*
* Make sure the next tick runs within a
* reasonable amount of time.
*/
- u64 delta = rq_clock_task(rq) - curr->se.exec_start;
+ u64 delta = rq_clock_task(rq) - donor->se.exec_start;
WARN_ON_ONCE(delta > (u64)NSEC_PER_SEC * 30);
}
- curr->sched_class->task_tick(rq, curr, 0);
+ donor->sched_class->task_tick(rq, donor, 0);
calc_load_nohz_remote(rq);
}
---
base-commit: a804c5742bff224d4cb4d25dd383554d598be32b
change-id: 20261016-remote-tick-proxy-237fc1da63c8
Best regards,
--
Shubhang Kaushik (Ampere) <sh@gentwo.org>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH v2] sched/core: Use the scheduling context for remote ticks
2026-10-21 17:15 [PATCH v2] sched/core: Use the scheduling context for remote ticks Shubhang Kaushik (Ampere)
@ 2026-10-21 20:09 ` John Stultz
2026-10-21 23:12 ` Shubhang
0 siblings, 1 reply; 3+ messages in thread
From: John Stultz @ 2026-10-21 20:09 UTC (permalink / raw)
To: Shubhang Kaushik (Ampere)
Cc: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
Valentin Schneider, K Prateek Nayak, Connor O'Brien,
Shubhang Kaushik, Christoph Lameter (Ampere),
linux-kernel
On Wed, Oct 21, 2026 at 10:15 AM Shubhang Kaushik (Ampere)
<sh@gentwo.org> wrote:
>
> sched_tick_remote() invokes task_tick() for rq->curr. With proxy
> execution, rq->curr is the mutex-owner execution context while
> rq->donor is the blocked task that supplies the scheduling context.
>
> A mutex-blocked task remains queued for proxy execution. If that task
> is SCHED_FIFO, or the only SCHED_RR task, sched_can_stop_tick() permits
> the full-nohz tick to stop. find_proxy_task() can then select its mutex
> owner as rq->curr while retaining the blocked task as rq->donor.
>
> sched_tick() and hrtick() already invoke task_tick() for rq->donor.
> Like task_tick(), the remote tick's full-nohz interval sanity check
> currently uses rq->curr. The proxy owner in rq->curr can have a stale
> se.exec_start before the accounting path updates it.
>
> Make sched_tick_remote() use rq->donor for both the class tick and the
> full-nohz tick-interval sanity check.
Hey! Thanks for chasing this down!
Apologies, as full nohz is a bit of a blind spot for me, but it seems
the commit message gets a little lost focusing on the proxy details,
which makes it a bit harder to understand how the underlying
assumption was broken.
Maybe can I suggest reworking it to something like:
---
In sched_tick_remote(), when adding proxy-exec support, an assumption
was made, which was: we're in full dynticks mode, so there can be only
one task on the rq. With only one task, we can assume rq->donor ==
rq->curr. So there wasn't a need to switch rq->curr reference to
rq->donor when proxy logic was added.
However, the full nohz rules are more complex. If a SCHED_FIFO task is
running, even if there are multiple tasks on the rq,
sched_can_stop_tick() allows the tick to stop since there is no forced
preemption of SCHED_FIFO. Similarly if there is only one SCHED_RR task
the tick can be stopped even if there are other lower-sched-class
tasks on the RQ.
This means in sched_tick_remote(), there may be more tasks on the
runqueue, which means we could be proxying (if a SCHED_FIFO task is
blocked on a SCHED_NORMAL task) and and rq->donor may not equal
rq->curr. This earlier assumption doesn't hold, and the references do
need to be switched to use rq->donor so the accounting is handled
properly, and to make it more consistent with rq->donor useage
elsewhere in the scheduler.
---
Also looking I see the comment at the top of the sched_tick_remote()
function "The [full dynticks mode] check is racy by nature" which
makes me wonder if that might also be involved here, and worth
mentioning?
The code change itself looks good to me though, so after tweaking the
commit message, feel free to add:
Acked-by: John Stultz <jstultz@google.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2] sched/core: Use the scheduling context for remote ticks
2026-10-21 20:09 ` John Stultz
@ 2026-10-21 23:12 ` Shubhang
0 siblings, 0 replies; 3+ messages in thread
From: Shubhang @ 2026-10-21 23:12 UTC (permalink / raw)
To: John Stultz
Cc: Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman,
Valentin Schneider, K Prateek Nayak, Connor O'Brien,
Shubhang Kaushik, Christoph Lameter (Ampere),
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3473 bytes --]
Hi John,
On Wed, 21 Oct 2026, John Stultz wrote:
> On Wed, Oct 21, 2026 at 10:15 AM Shubhang Kaushik (Ampere)
> <sh@gentwo.org> wrote:
>>
>> sched_tick_remote() invokes task_tick() for rq->curr. With proxy
>> execution, rq->curr is the mutex-owner execution context while
>> rq->donor is the blocked task that supplies the scheduling context.
>>
>> A mutex-blocked task remains queued for proxy execution. If that task
>> is SCHED_FIFO, or the only SCHED_RR task, sched_can_stop_tick() permits
>> the full-nohz tick to stop. find_proxy_task() can then select its mutex
>> owner as rq->curr while retaining the blocked task as rq->donor.
>>
>> sched_tick() and hrtick() already invoke task_tick() for rq->donor.
>> Like task_tick(), the remote tick's full-nohz interval sanity check
>> currently uses rq->curr. The proxy owner in rq->curr can have a stale
>> se.exec_start before the accounting path updates it.
>>
>> Make sched_tick_remote() use rq->donor for both the class tick and the
>> full-nohz tick-interval sanity check.
>
> Hey! Thanks for chasing this down!
>
> Apologies, as full nohz is a bit of a blind spot for me, but it seems
> the commit message gets a little lost focusing on the proxy details,
> which makes it a bit harder to understand how the underlying
> assumption was broken.
>
> Maybe can I suggest reworking it to something like:
> ---
> In sched_tick_remote(), when adding proxy-exec support, an assumption
> was made, which was: we're in full dynticks mode, so there can be only
> one task on the rq. With only one task, we can assume rq->donor ==
> rq->curr. So there wasn't a need to switch rq->curr reference to
> rq->donor when proxy logic was added.
>
> However, the full nohz rules are more complex. If a SCHED_FIFO task is
> running, even if there are multiple tasks on the rq,
> sched_can_stop_tick() allows the tick to stop since there is no forced
> preemption of SCHED_FIFO. Similarly if there is only one SCHED_RR task
> the tick can be stopped even if there are other lower-sched-class
> tasks on the RQ.
>
> This means in sched_tick_remote(), there may be more tasks on the
> runqueue, which means we could be proxying (if a SCHED_FIFO task is
> blocked on a SCHED_NORMAL task) and and rq->donor may not equal
> rq->curr. This earlier assumption doesn't hold, and the references do
> need to be switched to use rq->donor so the accounting is handled
> properly, and to make it more consistent with rq->donor useage
> elsewhere in the scheduler.
> ---
>
> Also looking I see the comment at the top of the sched_tick_remote()
> function "The [full dynticks mode] check is racy by nature" which
> makes me wonder if that might also be involved here, and worth
> mentioning?
>
> The code change itself looks good to me though, so after tweaking the
> commit message, feel free to add:
> Acked-by: John Stultz <jstultz@google.com>
>
Thanks for the review, agreed.
The full-nohz assumption is the important part:
sched_can_stop_tick() can legitimately stop the tick with multiple
tasks on the runqueue in the SCHED_FIFO and exactly one SCHED_RR cases.
A blocked SCHED_FIFO task can then remain rq->donor while proxy
execution runs its SCHED_NORMAL mutex owner as rq->curr.
The racy tick-stopped check can allow an extra or missed remote tick,
but is not required for the issue; the mismatch can occur while the
tick is legitimately stopped. I will clarify both points in v3 and add
your Acked-by tag.
Regards,
Shubhang Kaushik
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-21 23:21 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21 17:15 [PATCH v2] sched/core: Use the scheduling context for remote ticks Shubhang Kaushik (Ampere)
2026-10-21 20:09 ` John Stultz
2026-10-21 23:12 ` Shubhang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®