git: f6ffed44a8eb - main - vm: use atomic fetchadd in vm_page_sunbusy

From: Mateusz Guzik <mjg_at_FreeBSD.org>
Date: Wed, 17 Aug 2022 10:36:32 UTC
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=f6ffed44a8eb5d1ab89a18e60fb056aab2105be7

commit f6ffed44a8eb5d1ab89a18e60fb056aab2105be7
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2022-08-05 14:27:55 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2022-08-17 10:36:11 +0000

    vm: use atomic fetchadd in vm_page_sunbusy
    
    This also fixes a bug where not-last unbusy failed to post a release
    fence.
    
    Reviewed by:    markj (previous version), kib (previous version)
    Differential Revision:  https://reviews.freebsd.org/D36084
---
 sys/vm/vm_page.c | 26 ++++++--------------------
 1 file changed, 6 insertions(+), 20 deletions(-)

diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index e7500e9d3e71..defcebb286ae 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -973,27 +973,13 @@ vm_page_sunbusy(vm_page_t m)
 {
 	u_int x;
 
-	vm_page_assert_sbusied(m);
-
-	x = vm_page_busy_fetch(m);
-	for (;;) {
-		KASSERT(x != VPB_FREED,
-		    ("vm_page_sunbusy: Unlocking freed page."));
-		if (VPB_SHARERS(x) > 1) {
-			if (atomic_fcmpset_int(&m->busy_lock, &x,
-			    x - VPB_ONE_SHARER))
-				break;
-			continue;
-		}
-		KASSERT((x & ~VPB_BIT_WAITERS) == VPB_SHARERS_WORD(1),
-		    ("vm_page_sunbusy: invalid lock state"));
-		if (!atomic_fcmpset_rel_int(&m->busy_lock, &x, VPB_UNBUSIED))
-			continue;
-		if ((x & VPB_BIT_WAITERS) == 0)
-			break;
+	atomic_thread_fence_rel();
+	x = atomic_fetchadd_int(&m->busy_lock, -VPB_ONE_SHARER);
+	KASSERT(x != VPB_FREED, ("page %p is freed", m));
+	KASSERT(x != VPB_UNBUSIED && (x & VPB_BIT_SHARED) != 0,
+	    ("page %p not sbusied", m));
+	if (x == (VPB_SHARERS_WORD(1) | VPB_BIT_WAITERS))
 		wakeup(m);
-		break;
-	}
 }
 
 /*