Re: [PATCH 02/11] sched: Add helper to block retained proxy donors

K Prateek Nayak <[email protected]> Thu, 16 Jul 2026 23:17:53 +0530
Newsgroups dev.linux.lists.sched-ext,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hello Andrea,

On 7/16/2026 2:24 AM, Andrea Righi wrote:
> +/*
> + * Remove a retained proxy donor before changing its scheduler ownership.
> + * The caller holds p->pi_lock, so p cannot wake and migrate after block_task()
> + * drops it from the runqueue.
> + *
> + * Unlike the regular schedule() path, this must leave @p fully dequeued.
> + * DELAY_DEQUEUE may keep a blocked fair task queued with sched_delayed set,
> + * which would let the following sched_change preserve and re-enqueue it under
> + * the new scheduler. Complete an existing or newly-created delayed dequeue
> + * before returning.
> + */
> +void sched_proxy_block_task(struct rq *rq, struct task_struct *p)
> +{
> +	unsigned long state = READ_ONCE(p->__state);
> +
> +	lockdep_assert_held(&p->pi_lock);
> +	lockdep_assert_rq_held(rq);
> +
> +	if (!p->is_blocked || !task_on_rq_queued(p))
> +		return;
> +	if (WARN_ON_ONCE(state == TASK_RUNNING))
> +		return;
> +
> +	if (task_current_donor(rq, p)) {
> +		proxy_resched_idle(rq);

This should be proxy_reset_donor() else the current may try to
do a sched_yield() with idle as donor and you'll try calling
idle class' yield which will crash.

> +		/* Kick the execution context if @rq is remote. */
> +		resched_curr(rq);
> +	}
> +
> +	if (!p->se.sched_delayed)
> +		block_task(rq, p, state);
> +	if (p->se.sched_delayed)
> +		dequeue_task(rq, p, DEQUEUE_SLEEP | DEQUEUE_DELAYED |
> +			     DEQUEUE_NOCLOCK);

nit.

This case gets dealt by the sched_change_begin() which happens right
after scx_prepare_setscheduler(). Do we really need it here?

> +
> +	WARN_ON_ONCE(task_on_rq_queued(p));
> +	WARN_ON_ONCE(p->se.sched_delayed);

Very defensive :-) I personally think on_rq check should be
sufficient. Delayed but not on_rq would scream at wakeup.

> +}
> +
>  static inline void proxy_release_rq_lock(struct rq *rq, struct rq_flags *rf)
>  	__releases(__rq_lockp(rq))
>  {

Also kudos with the sched_ext + proxy demo. Very impressive to see
that latency reduction.

-- 
Thanks and Regards,
Prateek