aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2022-08-05 14:27:55 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2022-08-17 10:36:11 +0000
commitf6ffed44a8eb5d1ab89a18e60fb056aab2105be7 (patch)
tree8abce838b0e5c99014820df2107004bc1d847085 /sys
parentf7413197245cfd732d3072c12beb2e49d40d2b32 (diff)
Diffstat (limited to 'sys')
-rw-r--r--sys/vm/vm_page.c26
1 files 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;
- }
}
/*