Re: [PATCH 1/6] sched/proxy: Remove superfluous clear_task_blocked_in()

From: Peter Zijlstra

Date: Fri May 29 2026 - 05:36:55 EST


On Fri, May 29, 2026 at 12:15:09PM +0530, K Prateek Nayak wrote:
> Hello John,
>
> On 5/29/2026 4:50 AM, John Stultz wrote:
> > However, even with the fix I poined out, I've unfortunately hit races
> > with the ww_mutex selftest at the point of this patch in the series.
> > Basically between commit
> > 1b89b7b21bf5 ("sched/proxy: Remove superfluous clear_task_blocked_in()")
> > and
> > a8be1edac5a1 ("sched/proxy: Remove PROXY_WAKING")
> >
> > I'm currently tracing down exactly why the race is cropping up but I
> > believe the chunk removed in this case is avoiding cases where we end
> > up getting PROXY_WAKING set on a TASK_RUNNING task.


I'm struggling to make sense of this...

> This seems to be the failure path:
>
> /* Task p*/
> mutex_lock(mutex)
> ... try_to_wake_up(p)
> schedule_preempt_disabled() ttwu_runnable()
> __schedule() __task_rq_lock() /* Wins */
> rq_lock() /* Waits */ if (task_on_rq_queued(p))
> /*
> * p->is_blocked is still not set!
> * proxy_needs_return() bails out early.
> */
> ttwu_do_wakeup()
> p->__state = TASK_RUNNING;
> __tsk_rq_unlock();
> ...
> /* p->__state = TASK_RUNNING */
> prev_state = p->__state;
> if (prev_state && ...) {
> /*
> * Skipped since task is
> * already TASK_RUNNING
> */
> }
>
> /* p->is_blocked = 0; p->blocked_on = PROXY_WAKING */
> next = p;
>
> /* Returns from schedule_preempt_disabled()
> set_task_blocked_on(p, mutex)
>
> !!! p->blocked_on == PROXY_WAKING && p->blocked_on != mutex !!!
> ---
>
> Also proxy_needs_return() bails out too early - a wakeup from signal
> should still clear p->blocked_on even if p->wake_cpu is same as
> task_cpu().

esp. in the context of the full patch set. There was no migration,
therefore there is no need for a return migration. We're in
mutex_lock(), any exit path will clear blocked_on.

I don't see why we should have proxy_needs_return() unconditionally take
that lock and clear blocked_on.