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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to