svn commit: r363654 - head/sys/vm
Mark Johnston
markj at FreeBSD.org
Tue Jul 28 19:50:40 UTC 2020
Author: markj
Date: Tue Jul 28 19:50:39 2020
New Revision: 363654
URL: https://svnweb.freebsd.org/changeset/base/363654
Log:
vm_page_xbusy_claim(): Use atomics to update busy lock state.
vm_page_xbusy_claim() could clobber the waiter bit. For its original
use, kernel memory pages, this was not a problem since nothing would
ever block on the busy lock for such pages. r363607 introduced a new
use where this could in principle be a problem.
Fix the problem by using atomic_cmpset to update the lock owner. Since
this macro is defined only for INVARIANTS kernels the extra overhead
doesn't seem prohibitive.
Reported by: vangyzen
Reviewed by: alc, kib, vangyzen
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D25859
Modified:
head/sys/vm/vm_page.h
Modified: head/sys/vm/vm_page.h
==============================================================================
--- head/sys/vm/vm_page.h Tue Jul 28 19:35:24 2020 (r363653)
+++ head/sys/vm/vm_page.h Tue Jul 28 19:50:39 2020 (r363654)
@@ -772,8 +772,13 @@ void vm_page_assert_pga_writeable(vm_page_t m, uint16_
#define VM_PAGE_ASSERT_PGA_WRITEABLE(m, bits) \
vm_page_assert_pga_writeable(m, bits)
#define vm_page_xbusy_claim(m) do { \
+ u_int _busy_lock; \
+ \
vm_page_assert_xbusied_unchecked((m)); \
- (m)->busy_lock = VPB_CURTHREAD_EXCLUSIVE; \
+ do { \
+ _busy_lock = atomic_load_int(&(m)->busy_lock); \
+ } while (!atomic_cmpset_int(&(m)->busy_lock, _busy_lock, \
+ (_busy_lock & VPB_BIT_FLAGMASK) | VPB_CURTHREAD_EXCLUSIVE)); \
} while (0)
#else
#define VM_PAGE_OBJECT_BUSY_ASSERT(m) (void)0
More information about the svn-src-head
mailing list