diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-25 09:10:10 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-25 09:10:10 -0700 |
commit | 0146da0d4cecad571f69f02fe35d75d6dba9723c (patch) | |
tree | aa30f42b243acbe518d7e8189a5bf206a002f43d /kernel | |
parent | 682b26bd80f96c2e4da3eb6dcec8bf684b79151c (diff) | |
parent | 84a24bf8c52e66b7ac89ada5e3cfbe72d65c1896 (diff) | |
download | linux-0146da0d4cecad571f69f02fe35d75d6dba9723c.tar.bz2 |
Merge tag 'locking_urgent_for_v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fix from Borislav Petkov:
"Fix ordering in the queued writer lock's slowpath"
* tag 'locking_urgent_for_v5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/qrwlock: Fix ordering in queued_write_lock_slowpath()
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/locking/qrwlock.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/kernel/locking/qrwlock.c b/kernel/locking/qrwlock.c index 4786dd271b45..b94f3831e963 100644 --- a/kernel/locking/qrwlock.c +++ b/kernel/locking/qrwlock.c @@ -60,6 +60,8 @@ EXPORT_SYMBOL(queued_read_lock_slowpath); */ void queued_write_lock_slowpath(struct qrwlock *lock) { + int cnts; + /* Put the writer into the wait queue */ arch_spin_lock(&lock->wait_lock); @@ -73,9 +75,8 @@ void queued_write_lock_slowpath(struct qrwlock *lock) /* When no more readers or writers, set the locked flag */ do { - atomic_cond_read_acquire(&lock->cnts, VAL == _QW_WAITING); - } while (atomic_cmpxchg_relaxed(&lock->cnts, _QW_WAITING, - _QW_LOCKED) != _QW_WAITING); + cnts = atomic_cond_read_relaxed(&lock->cnts, VAL == _QW_WAITING); + } while (!atomic_try_cmpxchg_acquire(&lock->cnts, &cnts, _QW_LOCKED)); unlock: arch_spin_unlock(&lock->wait_lock); } |