Re: [PATCH 1/7] sched/core: Fix pick_next_task() self recursion

From: Peter Zijlstra

Date: Fri Sep 25 2026 - 10:41:29 EST


On Thu, Sep 03, 2026 at 07:13:35PM +0800, Aaron Lu wrote:
> On Fri, Aug 28, 2026 at 12:17:00PM +0200, Peter Zijlstra wrote:
> > It is possible for another sibling to end up in pick_next_task() when:
> >
> > pick_next_task()
> > pick_task()
> > sched_class::pick_task()
> >
> > drops the core wide rq->lock. In this case they end up trampling the core wide
> > task selection state, possibly leading to NULL derefs. Detect this case by
> > keeping a local copy of core_task_seq, a value that is incremented on
> > {en,de}queue and schedule.
> >
> > 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.
>
> For the uncookied no-sync fast path, we should check if core wide is
> still uncookied after lock is re-acquired? Something like below, or we
> can pick an uncookied task when sibling picked a cookied one:
>
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index cd0149f5f6693..781f751acdb5b 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -6314,6 +6314,14 @@ pick_next_task(struct rq *rq, struct rq_flags *rf)
> goto restart;
>
> 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;
> /*
>
> We can also do a core_task_seq check above but if sibling picked an
> uncookied task, it's actually OK for this rq to go this fast path so I
> chose to check rq->core->core_cookie here.

Indeed! I had considered adding the seq check here, but didn't see any
problem it would solve. Clearly I missed this case.

Let me add this.