svn commit: r307064 - head/sys/vm
Konstantin Belousov
kib at FreeBSD.org
Tue Oct 11 18:09:39 UTC 2016
Author: kib
Date: Tue Oct 11 18:09:37 2016
New Revision: 307064
URL: https://svnweb.freebsd.org/changeset/base/307064
Log:
When downgrading exclusively busied page to shared-busy state, wakeup
waiters. Otherwise, owners of the shared-busy state are left blocked
and might get into a deadlock.
Note that the vm_page_busy_downgrade() function is not used in the
tree right now.
Reported and tested by: pho (previous version)
Reviewed by: alc, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D8195
Modified:
head/sys/vm/vm_page.c
Modified: head/sys/vm/vm_page.c
==============================================================================
--- head/sys/vm/vm_page.c Tue Oct 11 17:47:54 2016 (r307063)
+++ head/sys/vm/vm_page.c Tue Oct 11 18:09:37 2016 (r307064)
@@ -655,15 +655,26 @@ void
vm_page_busy_downgrade(vm_page_t m)
{
u_int x;
+ bool locked;
vm_page_assert_xbusied(m);
+ locked = mtx_owned(vm_page_lockptr(m));
for (;;) {
x = m->busy_lock;
x &= VPB_BIT_WAITERS;
+ if (x != 0 && !locked)
+ vm_page_lock(m);
if (atomic_cmpset_rel_int(&m->busy_lock,
- VPB_SINGLE_EXCLUSIVER | x, VPB_SHARERS_WORD(1) | x))
+ VPB_SINGLE_EXCLUSIVER | x, VPB_SHARERS_WORD(1)))
break;
+ if (x != 0 && !locked)
+ vm_page_unlock(m);
+ }
+ if (x != 0) {
+ wakeup(m);
+ if (!locked)
+ vm_page_unlock(m);
}
}
More information about the svn-src-all
mailing list