mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Tejun Heo <tj@kernel.org>
Cc: mingo@kernel.org, juri.lelli@redhat.com,
	vincent.guittot@linaro.org, dietmar.eggemann@arm.com,
	rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de,
	vschneid@redhat.com, kprateek.nayak@amd.com,
	linux-kernel@vger.kernel.org, ziqianlu@bytedance.com
Subject: Re: [PATCH v2 01/12] sched/core: Fix pick_next_task() self recursion
Date: Wed, 11 Nov 2026 11:45:21 +0100	[thread overview]
Message-ID: <20261111104521.GL2668200@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <69d54f4e77e99f41ea0fb22b7381a522@kernel.org>

On Tue, Nov 10, 2026 at 02:30:33PM -1000, Tejun Heo wrote:
> Hello, Peter.
> 
> On Sat, Nov 07, 2026 at 12:59:14PM +0100, Peter Zijlstra wrote:
> > Since RETRY_TASK is only possible when a higher priority task gets enqueued
> > during the lock break, this must mean core_task_seq will also be incremented
> > and is thus completely covered by the seq number mismatch.
> 
> This doesn't hold for sched_ext, which returns RETRY_TASK whenever
> dispatch released the rq lock, e.g. ops.dispatch() inserting a task into
> a remote CPU's local DSQ, with no enqueue or dequeue on this core.
> 
> [ ... ]
> 
> >  		if (!next->core_cookie) {
> > +			/*
> > +			 * pick_task() can drop the core rq lock through
> > +			 * newidle balance. If a sibling established a
> > +			 * core-wide cookie while the lock was dropped, the
> > +			 * uncookied no-sync fast path is no longer valid.
> > +			 */
> > +			if (unlikely(rq->core->core_cookie))
> > +				goto restart;
> > +
> >  			rq->core_pick = NULL;
> >  			rq->core_dl_server = NULL;
> 
> This only catches a sibling selection which has already committed. One
> still in flight has reset core_cookie to 0 and may have set this CPU's
> core_pick, which the fast path then clears without changing
> core_task_seq. It needs three or more SMT siblings (e.g. POWER), so it
> isn't a common case:
> 
> 1. CPU2 is in the fast path and drops the lock in newidle.
> 2. CPU1 starts a core-wide selection: bumps core_task_seq, resets
>    core_cookie, sets rq2->core_pick and drops the lock in
>    pick_task(rq3).
> 3. CPU2 retakes the lock, sees core_cookie == 0, clears rq2->core_pick
>    and commits.
> 4. CPU1 retakes the lock, passes the seq check and hands the NULL
>    rq2->core_pick to cookie_equals().
> 
> This becomes reachable with 10/12 ("sched/fair: Reflow pick_task_fair()
> / newidle"), where pick_task_fair() can drop the lock in newidle without
> returning RETRY_TASK, and reliably oopses in __schedule() on an SMT4 VM.

Nice find.

> One way could be bumping core_task_seq when the fast path commits after
> the seq moved, so that the in-flight selection restarts. Another would
> be testing seq != core_task_seq instead of core_cookie, at the cost of
> restarting on any enqueue or dequeue during the lock break.

It always did bother me this test wasn't the same we used below. Let
them both be: 'seq != rq->core->core_task_seq'.

> [ ... ]
> 
> >  		p = pick_task(rq_i, rf);
> > -		if (unlikely(p == RETRY_TASK)) {
> > +		if (unlikely(seq != rq->core->core_task_seq ||
> > +			     WARN_ON_ONCE(p == RETRY_TASK))) {
> 
> As sched_ext can return RETRY_TASK with core_task_seq unchanged, this
> triggers reliably with a BPF scheduler running cookied tasks. The
> restart is still correct. Can the WARN_ON_ONCE() be dropped? The plain
> RETRY_TASK test is still needed as the seq can match.

Sure, dropped the WARN.

---
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6391,13 +6391,7 @@ pick_next_task(struct rq *rq, struct rq_
 		}
 
 		if (!next->core_cookie) {
-			/*
-			 * pick_task() can drop the core rq lock through
-			 * newidle balance. If a sibling established a
-			 * core-wide cookie while the lock was dropped, the
-			 * uncookied no-sync fast path is no longer valid.
-			 */
-			if (unlikely(rq->core->core_cookie))
+			if (unlikely(seq != rq->core->core_task_seq))
 				goto restart;
 
 			rq->core_pick = NULL;
@@ -6431,8 +6425,7 @@ pick_next_task(struct rq *rq, struct rq_
 			update_rq_clock(rq_i);
 
 		p = pick_task(rq_i, rf);
-		if (unlikely(seq != rq->core->core_task_seq ||
-			     WARN_ON_ONCE(p == RETRY_TASK))) {
+		if (unlikely(seq != rq->core->core_task_seq || p == RETRY_TASK)) {
 			/* rq lock may have been dropped, clocks invalidated */
 			core_clock_updated = false;
 			if (!(rq->clock_update_flags & RQCF_UPDATED))

  reply	other threads:[~2026-11-11 10:45 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07 11:59 [PATCH v2 00/12] sched: core-sched fixes and balancing Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 01/12] sched/core: Fix pick_next_task() self recursion Peter Zijlstra
2026-11-11  0:30   ` Tejun Heo
2026-11-11 10:45     ` Peter Zijlstra [this message]
2026-11-07 11:59 ` [PATCH v2 02/12] sched/core: Introduce rq_drop_lock() Peter Zijlstra
2026-11-08  9:25   ` Kayra Cizmeci
2026-11-11 10:46     ` Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 03/12] sched/core: Decompose update_rq_clock() Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 04/12] sched/core: Make __update_rq_clock() skip updates on UPDATED Peter Zijlstra
2026-11-11  1:11   ` Tejun Heo
2026-11-11 10:28     ` Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 05/12] sched/core: Abstract/fix rq_clock_start_loop_update() Peter Zijlstra
2026-11-08 22:26   ` Kayra Cizmeci
2026-11-11  9:10     ` K Prateek Nayak
2026-11-11  9:51       ` Kayra Cizmeci
2026-11-07 11:59 ` [PATCH v2 06/12] sched/core: New rq_{pin,drop,repin,unpin}_lock() semantics Peter Zijlstra
2026-11-11 10:41   ` Tejun Heo
2026-11-07 11:59 ` [PATCH v2 07/12] sched/core: Simplify/fix time updates Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 08/12] sched/core: Allow newidle for core-sched Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 09/12] sched/rt: Add early exit on balance path Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 10/12] sched/fair: Reflow pick_task_fair() / newidle Peter Zijlstra
2026-11-11 11:02   ` Tejun Heo
2026-11-07 11:59 ` [PATCH v2 11/12] sched/fair: Push sched_balance_newidle() unlock down Peter Zijlstra
2026-11-07 11:59 ` [PATCH v2 12/12] sched: Remove sched_class::balance() Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261111104521.GL2668200@noisy.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=bsegall@google.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=juri.lelli@redhat.com \
    --cc=kprateek.nayak@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=tj@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=ziqianlu@bytedance.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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®