mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-11-12 12:30:17 +01:00
futex: Ensure get_futex_key_refs() always implies a barrier
Commitb0c29f79ec(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 commit11d4616bd0(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 bionic's mutex implementation on an arm64 multi-cluster system. Signed-off-by: Catalin Marinas <[email protected]> Reported-by: Matteo Franchin <[email protected]> Fixes:b0c29f79ec(futexes: Avoid taking the hb->lock if there's nothing to wake up) Acked-by: Davidlohr Bueso <[email protected]> Tested-by: Mike Galbraith <[email protected]> Cc: <[email protected]> Cc: Darren Hart <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Paul E. McKenney <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
1 parent
0429fbc0bd
commit
76835b0ebf
1 file changed
+2
@@ -343,6 +343,8 @@ static void get_futex_key_refs(union futex_key *key)
|
||||
case FUT_OFF_MMSHARED:
|
||||
futex_get_mm(key); /* implies MB (B) */
|
||||
break;
|
||||
default:
|
||||
smp_mb(); /* explicit MB (B) */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user