Re: [PATCH] sched/proxy_exec: Handle sched_delayed owner in find_proxy_task()

From: soolaugust

Date: Tue Mar 03 2026 - 01:30:35 EST


From: zhidao su <suzhidao@xxxxxxxxxx>

On 3/3/2026 11:29 AM, K Prateek Nayak wrote:
> Just switching to idle will not alter the EEVDF state and the pick
> will still converge on the same task whose owner will still be
> delayed.
>
> [...]
> ... And the cycle repeats with preemption disabled !!!
>
> This is terrible since blocked owner can be delayed on a busy runqueue
> for more than a few tick - sure it is a transient state but it can last
> for a while depending on the state of the cfs_rq where it is delayed,
> up to few 10s of milliseconds in a practical worst case scenario.

Agreed - the spinloop analysis is correct. pick_next_task() keeps
returning the same blocked donor; proxy_resched_idle() bounces off
idle each cycle until sched_delayed clears. Tens of milliseconds of
that is clearly unacceptable.

> proxy_deactivate() is correct to do for now until we get to the
> blocked owner handling.

Right. I'll send a v2 that keeps the two checks as separate blocks
(the conceptual distinction is worth preserving for when the blocked-
owner series lands), but uses proxy_deactivate() for both:

if (!READ_ONCE(owner->on_rq)) {
return proxy_deactivate(rq, donor);
}
if (owner->se.sched_delayed) {
/*
* Owner is in EEVDF deferred-dequeue: still physically on
* the runqueue but has called schedule(). A sched_delayed
* task never has blocked_on set, so the chain cannot be
* followed further. Deactivate the donor for now; proper
* handling will come with the blocked-owner series.
*
* XXX: Don't handle sched_delayed owners yet.
*/
return proxy_deactivate(rq, donor);
}

The comment replaces the shared "XXX" with per-case rationale, making
it clearer why they are handled differently once proper support lands.

Does that work, or would you prefer the two conditions be collapsed
back into one?