Re: [PATCH 05/16] sched: Add sched_ext hooks for proxy execution

From: Andrea Righi

Date: Fri Sep 25 2026 - 04:23:48 EST


On Thu, Sep 24, 2026 at 09:51:07AM +0200, Peter Zijlstra wrote:
> On Tue, Sep 22, 2026 at 06:51:44PM +0200, Andrea Righi wrote:
> > Proxy execution splits the scheduling context (the donor) from the
> > execution context (the lock owner). sched_ext needs to observe that
> > split at three points in __schedule():
> >
> > - whether a blocked EXT task can be retained on the runqueue as a
> > donor,
> > - when a donor's scheduling context starts driving a lock owner,
> > - after proxy resolution, when deferred reenqueue work that was blocked
> > by an active proxy relationship can be retried.
> >
> > Introduce scx_allow_proxy_exec(), scx_proxy_donor_start() and
> > scx_proxy_reenqueue_retry(), and add their call sites in __schedule().
> > The implementations are empty here and are filled in by the sched_ext
> > changes that follow, so that all the sched core changes needed by proxy
> > execution stay together in the preparatory patches.
> >
> > SCHED_PROXY_EXEC still depends on !SCHED_CLASS_EXT, so the new hooks are
> > inert: they are compiled out with CONFIG_SCHED_CLASS_EXT=n and
> > unreachable otherwise.
> >
> > This is a preparatory change to support proxy execution with sched_ext.
> > No functional change.
> >
> > Signed-off-by: Andrea Righi <arighi@xxxxxxxxxx>
> > ---
>
> > @@ -7243,6 +7242,7 @@ static void __sched notrace __schedule(int sched_mode)
> > }
> > if (next == rq->idle) {
> > zap_balance_callbacks(rq);
> > + scx_proxy_reenqueue_retry(rq, next);
> > goto keep_resched;
> > }
> > }
> > @@ -7263,6 +7263,8 @@ static void __sched notrace __schedule(int sched_mode)
> > donor->sched_class->put_prev_task(rq, donor, donor);
> > donor->sched_class->set_next_task(rq, donor, true);
> > }
> > + scx_proxy_donor_start(rq);
> > + scx_proxy_reenqueue_retry(rq, next);
> > } else {
> > rq_set_donor(rq, next);
> > }
>
> > diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
> > index f60894dbf0623..aaa6ee66917e8 100644
> > --- a/kernel/sched/ext/ext.c
> > +++ b/kernel/sched/ext/ext.c
>
> > @@ -1110,6 +1115,10 @@ static void schedule_deferred_locked(struct rq *rq)
> > schedule_deferred(rq);
> > }
> >
> > +void scx_proxy_reenqueue_retry(struct rq *rq)
> > +{
> > +}
>
> Doesn't match its prototype, also, I'm a little confused about the next
> argument in the next == rq->idle case.

Ah yes, the empty stub has the wrong signature (fixed now in my
scx-proxy-exec-next branch). Thanks for catching it.

>
> Hmm, you seem to be using the argument like:
>
> bool proxy = next != rq->donor;
>
> And I suppose that works. But that seems to be about the tick, not
> putting current back on a dsq.

Yes, it's used for the NO_HZ_FULL tick bookkeeping.

In the next == rq->idle case, find_proxy_task() has called proxy_resched_idle(),
which sets rq->donor to idle too. Passing next through the hook lets the tick
bookkeeping see that proxy execution has stopped and clear its proxy tick state.

And the reenqueue retry is separate work in the same hook. I moved both actions
in the same hook to avoid adding another call from the sched core, but I agree
it looks a bit confusing.

-Andrea

>
> > diff --git a/kernel/sched/ext/ext.h b/kernel/sched/ext/ext.h
> > index 0012f708a5504..cca3f7c97b788 100644
> > --- a/kernel/sched/ext/ext.h
> > +++ b/kernel/sched/ext/ext.h
> > @@ -20,6 +20,9 @@ void scx_rq_deactivate(struct rq *rq);
> > int scx_check_setscheduler(struct task_struct *p, int policy);
> > bool task_should_scx(int policy);
> > bool scx_allow_ttwu_queue(const struct task_struct *p);
> > +bool scx_allow_proxy_exec(const struct task_struct *p);
> > +void scx_proxy_donor_start(struct rq *rq);
> > +void scx_proxy_reenqueue_retry(struct rq *rq, struct task_struct *next);
> > void init_sched_ext_class(void);
> > void __scx_update_idle(struct rq *rq, bool idle, bool do_notify);
> >