• Catalin Marinas's avatar
    futex: Ensure get_futex_key_refs() always implies a barrier · 19f4b01d
    Catalin Marinas authored
    commit 76835b0e upstream.
    
    Commit b0c29f79 (futexes: Avoid taking the hb->lock if there's
    nothing to wake up) changes the futex code to avoid taking a lock when
    there are no waiters. This code has been subsequently fixed in commit
    11d4616b (futex: revert back to the explicit waiter counting code).
    Both the original commit and the fix-up rely on get_futex_key_refs() to
    always imply a barrier.
    
    However, for private futexes, none of the cases in the switch statement
    of get_futex_key_refs() would be hit and the function completes without
    a memory barrier as required before checking the "waiters" in
    futex_wake() -> hb_waiters_pending(). The consequence is a race with a
    thread waiting on a futex on another CPU, allowing the waker thread to
    read "waiters == 0" while the waiter thread to have read "futex_val ==
    locked" (in kernel).
    
    Without this fix, the problem (user space deadlocks) can be seen with
    Android bioni...
    19f4b01d
futex.c 80.9 KB