• Peter Zijlstra's avatar
    futex/pi: Fix recursive rt_mutex waiter state · fbeb558b
    Peter Zijlstra authored
    Some new assertions pointed out that the existing code has nested rt_mutex wait
    state in the futex code.
    
    Specifically, the futex_lock_pi() cancel case uses spin_lock() while there
    still is a rt_waiter enqueued for this task, resulting in a state where there
    are two waiters for the same task (and task_struct::pi_blocked_on gets
    scrambled).
    
    The reason to take hb->lock at this point is to avoid the wake_futex_pi()
    EAGAIN case.
    
    This happens when futex_top_waiter() and rt_mutex_top_waiter() state becomes
    inconsistent. The current rules are such that this inconsistency will not be
    observed.
    
    Notably the case that needs to be avoided is where futex_lock_pi() and
    futex_unlock_pi() interleave such that unlock will fail to observe a new
    waiter.
    
    *However* the case at hand is where a waiter is leaving, in this case the race
    means a waiter that is going away is not observed -- which is harmless,
    provided this race is explicitly handled.
    
    This is a somewhat dangerous proposition because the converse race is not
    observing a new waiter, which must absolutely not happen. But since the race is
    valid this cannot be asserted.
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Reviewed-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Reviewed-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
    Tested-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
    Link: https://lkml.kernel.org/r/20230915151943.GD6743@noisy.programming.kicks-ass.net
    fbeb558b
pi.c 33.4 KB