svn commit: r255244 - head/sys/vm
Konstantin Belousov
kib at FreeBSD.org
Thu Sep 5 12:54:41 UTC 2013
Author: kib
Date: Thu Sep 5 12:54:40 2013
New Revision: 255244
URL: http://svnweb.freebsd.org/changeset/base/255244
Log:
The vm_page_trysbusy() should not fail when shared busy counter or
VPB_BIT_WAITERS flag were changed between reading of busy_lock and the
cas. The vm_page_sbusy(), which is the only user of
vm_page_trysbusy() in the tree, panics on the failure, which in these
cases is transient and do not mean that the current page state
prevents sbusying.
Retry the operation inside vm_page_trysbusy() if cas failed, only
return a failure when VPB_BIT_SHARED is cleared.
Reported and tested by: pho
Reviewed by: attilio
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/vm/vm_page.c
Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c Thu Sep 5 12:35:23 2013 (r255243)
+++ head/sys/vm/vm_page.c Thu Sep 5 12:54:40 2013 (r255244)
@@ -602,9 +602,13 @@ vm_page_trysbusy(vm_page_t m)
{
u_int x;
- x = m->busy_lock;
- return ((x & VPB_BIT_SHARED) != 0 &&
- atomic_cmpset_acq_int(&m->busy_lock, x, x + VPB_ONE_SHARER));
+ for (;;) {
+ x = m->busy_lock;
+ if ((x & VPB_BIT_SHARED) == 0)
+ return (0);
+ if (atomic_cmpset_acq_int(&m->busy_lock, x, x + VPB_ONE_SHARER))
+ return (1);
+ }
}
/*
More information about the svn-src-head
mailing list