Messages in this thread | | | From | Waiman Long <> | Subject | Re: [PATCH] locking/qrwlock: Fix ordering in queued_write_lock_slowpath | Date | Thu, 15 Apr 2021 11:07:56 -0400 |
| |
On 4/15/21 10:25 AM, Ali Saidi wrote: > While this code is executed with the wait_lock held, a reader can > acquire the lock without holding wait_lock. The writer side loops > checking the value with the atomic_cond_read_acquire(), but only truly > acquires the lock when the compare-and-exchange is completed > successfully which isn’t ordered. The other atomic operations from this > point are release-ordered and thus reads after the lock acquisition can > be completed before the lock is truly acquired which violates the > guarantees the lock should be making. > > Fixes: b519b56e378ee ("locking/qrwlock: Use atomic_cond_read_acquire() when spinning in qrwloc") > Signed-off-by: Ali Saidi <alisaidi@amazon.com> > Cc: stable@vger.kernel.org > --- > kernel/locking/qrwlock.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/kernel/locking/qrwlock.c b/kernel/locking/qrwlock.c > index 4786dd271b45..10770f6ac4d9 100644 > --- a/kernel/locking/qrwlock.c > +++ b/kernel/locking/qrwlock.c > @@ -73,8 +73,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, > + atomic_cond_read_relaxed(&lock->cnts, VAL == _QW_WAITING); > + } while (atomic_cmpxchg_acquire(&lock->cnts, _QW_WAITING, > _QW_LOCKED) != _QW_WAITING); > unlock: > arch_spin_unlock(&lock->wait_lock);
I think the original code isn't wrong. The read_acquire provides the acquire barrier for cmpxchg. Because of conditional dependency, the wait_lock unlock won't happen until the cmpxchg succeeds. Without doing a read_acquire, there may be a higher likelihood that the cmpxchg may fail.
Anyway, I will let Will or Peter chime in on this as I am not as proficient as them on this topic.
Cheers, Longman
| |