From 38baca17e01e138dc9c7211c0f6cb4ba74b14449 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Thu, 7 Jan 2021 07:45:49 +0100 Subject: [PATCH] lockmgr: fix upgrade TRYUPGRADE requests kept failing when they should not have due to wrong macro used to count readers. Fixes: f6b091fbbd77cbb0 ("lockmgr: rewrite upgrade to stop always dropping the lock") Noted by: asomers Differential Revision: https://reviews.freebsd.org/D27947 --- sys/kern/kern_lock.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 98c6cafde702..091abcda2a1e 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -984,17 +984,19 @@ lockmgr_upgrade(struct lock *lk, u_int flags, struct lock_object *ilk, op = flags & LK_TYPE_MASK; v = lockmgr_read_value(lk); for (;;) { - if (LK_SHARERS_LOCK(v) > 1) { + if (LK_SHARERS(v) > 1) { if (op == LK_TRYUPGRADE) { LOCK_LOG2(lk, "%s: %p failed the nowait upgrade", __func__, lk); error = EBUSY; goto out; } - if (lockmgr_sunlock_try(lk, &v)) { + if (atomic_fcmpset_rel_ptr(&lk->lk_lock, &v, + v - LK_ONE_SHARER)) { lockmgr_note_shared_release(lk, file, line); goto out_xlock; } + continue; } MPASS((v & ~LK_ALL_WAITERS) == LK_SHARERS_LOCK(1));