[PATCH v33 2/7] sched/core: Use the scheduling context for remote ticks
From: John Stultz
Date: Fri Oct 23 2026 - 18:07:09 EST
From: "Shubhang Kaushik (Ampere)" <sh@xxxxxxxxxx>
sched_tick_remote() assumes that a CPU in full dynticks mode has only
one running task. It therefore assumes that proxy execution cannot be
active and that rq->curr == rq->donor.
However, sched_can_stop_tick() can stop the tick with multiple tasks on
the runqueue. With exactly one SCHED_RR task, the tick is not needed for
round-robin timeslice rotation. When there are no SCHED_RR tasks,
SCHED_FIFO tasks do not require the tick because they have no forced
tick preemption. Lower scheduling-class tasks can still be queued in
both cases.
Consequently, a SCHED_FIFO task blocked on a SCHED_NORMAL mutex owner
can remain rq->donor while find_proxy_task() selects the owner to
execute as rq->curr. sched_tick_remote() can therefore run with
rq->curr != rq->donor.
The full-nohz state check in sched_tick_remote() is intentionally racy
and can allow an extra or missed remote tick. This issue does not rely
on that race: the tick can be legitimately stopped in the cases above.
Use rq->donor for the remote class tick and its full-nohz tick-interval
sanity check, matching sched_tick() and hrtick().
Fixes: 7de9d4f94638 ("sched: Start blocked_on chain processing in find_proxy_task()")
Signed-off-by: Shubhang Kaushik (Ampere) <sh@xxxxxxxxxx>
Signed-off-by: John Stultz <jstultz@xxxxxxxxxx>
---
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: K Prateek Nayak <kprateek.nayak@xxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Juri Lelli <juri.lelli@xxxxxxxxxx>
Cc: Vincent Guittot <vincent.guittot@xxxxxxxxxx>
Cc: Valentin Schneider <vschneid@xxxxxxxxxx>
Cc: Suleiman Souhlal <suleiman@xxxxxxxxxx>
Cc: Andrea Righi <arighi@xxxxxxxxxx>
Cc: Metin Kaya <Metin.Kaya@xxxxxxx>
Cc: Dietmar Eggemann <dietmar.eggemann@xxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: Zimuzo Ezeozue <zezeozue@xxxxxxxxxx>
Cc: Waiman Long <longman@xxxxxxxxxx>
Cc: Boqun Feng <boqun.feng@xxxxxxxxx>
Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxx>
Cc: Joel Fernandes <joelagnelf@xxxxxxxxxx>
Cc: Qais Yousef <qyousef@xxxxxxxxxxx>
Cc: Xuewen Yan <xuewen.yan94@xxxxxxxxx>
Cc: kuyo chang <kuyo.chang@xxxxxxxxxxxx>
Cc: hupu <hupu.gm@xxxxxxxxx>
Cc: Zhan Xusheng <zhanxusheng@xxxxxxxxxx>
Cc: zhidao su (Xiaomi) <soolaugust@xxxxxxxxx>
Cc: Hui Su <sh_def@xxxxxxx>
Cc: Shubhang Kaushik (Ampere) <sh@xxxxxxxxxx>
Cc: kernel-team@xxxxxxxxxxx
---
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 0ab15f03cb947..729ebaca35e1a 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);
}
--
2.56.0.257.gf7497c7d27-goog