svn commit: r251029 - in user/attilio/vmobj-readlock/sys: kern vm
Attilio Rao
attilio at FreeBSD.org
Mon May 27 16:12:41 UTC 2013
Author: attilio
Date: Mon May 27 16:12:39 2013
New Revision: 251029
URL: http://svnweb.freebsd.org/changeset/base/251029
Log:
Rework vm_page_sleep_if_busy() in order to acquire the page lock iff
it requires to sleep.
This saves some further page_lock acquisitions that were added during
the development.
Sponsored by: EMC / Isilon storage division
Modified:
user/attilio/vmobj-readlock/sys/kern/subr_uio.c
user/attilio/vmobj-readlock/sys/kern/vfs_bio.c
user/attilio/vmobj-readlock/sys/vm/vm_fault.c
user/attilio/vmobj-readlock/sys/vm/vm_object.c
user/attilio/vmobj-readlock/sys/vm/vm_page.c
Modified: user/attilio/vmobj-readlock/sys/kern/subr_uio.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/kern/subr_uio.c Mon May 27 15:51:03 2013 (r251028)
+++ user/attilio/vmobj-readlock/sys/kern/subr_uio.c Mon May 27 16:12:39 2013 (r251029)
@@ -107,9 +107,9 @@ vm_pgmoveco(vm_map_t mapa, vm_offset_t k
VM_OBJECT_WLOCK(uobject);
retry:
if ((user_pg = vm_page_lookup(uobject, upindex)) != NULL) {
- vm_page_lock(user_pg);
if (vm_page_sleep_if_busy(user_pg, "vm_pgmoveco"))
goto retry;
+ vm_page_lock(user_pg);
pmap_remove_all(user_pg);
vm_page_free(user_pg);
vm_page_unlock(user_pg);
Modified: user/attilio/vmobj-readlock/sys/kern/vfs_bio.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/kern/vfs_bio.c Mon May 27 15:51:03 2013 (r251028)
+++ user/attilio/vmobj-readlock/sys/kern/vfs_bio.c Mon May 27 16:12:39 2013 (r251029)
@@ -3459,10 +3459,9 @@ allocbuf(struct buf *bp, int size)
m = bp->b_pages[i];
KASSERT(m != bogus_page,
("allocbuf: bogus page found"));
- do {
- vm_page_lock(m);
- } while (vm_page_sleep_if_busy(m,
- "biodep"));
+ while (vm_page_sleep_if_busy(m,
+ "biodep"))
+ continue;
bp->b_pages[i] = NULL;
vm_page_unwire(m, 0);
Modified: user/attilio/vmobj-readlock/sys/vm/vm_fault.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/vm_fault.c Mon May 27 15:51:03 2013 (r251028)
+++ user/attilio/vmobj-readlock/sys/vm/vm_fault.c Mon May 27 16:12:39 2013 (r251029)
@@ -379,10 +379,7 @@ RetryFault:;
unlock_map(&fs);
if (fs.m == vm_page_lookup(fs.object,
fs.pindex)) {
- vm_page_lock(fs.m);
- if (!vm_page_sleep_if_busy(fs.m,
- "vmpfw"))
- vm_page_unlock(fs.m);
+ vm_page_sleep_if_busy(fs.m, "vmpfw");
}
vm_object_pip_wakeup(fs.object);
VM_OBJECT_WUNLOCK(fs.object);
Modified: user/attilio/vmobj-readlock/sys/vm/vm_object.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/vm_object.c Mon May 27 15:51:03 2013 (r251028)
+++ user/attilio/vmobj-readlock/sys/vm/vm_object.c Mon May 27 16:12:39 2013 (r251029)
@@ -871,7 +871,6 @@ rescan:
np = TAILQ_NEXT(p, listq);
if (p->valid == 0)
continue;
- vm_page_lock(p);
if (vm_page_sleep_if_busy(p, "vpcwai")) {
if (object->generation != curgeneration) {
if ((flags & OBJPC_SYNC) != 0)
@@ -882,7 +881,6 @@ rescan:
np = vm_page_find_least(object, pi);
continue;
}
- vm_page_unlock(p);
if (!vm_object_page_remove_write(p, flags, &clearobjflags))
continue;
@@ -1927,8 +1925,12 @@ again:
vm_page_unlock(p);
continue;
}
- if (vm_page_sleep_if_busy(p, "vmopar"))
+ if ((p->oflags & VPO_BUSY) != 0 || p->busy != 0) {
+ VM_OBJECT_WUNLOCK(object);
+ vm_page_sleep(p, "vmopar");
+ VM_OBJECT_WLOCK(object);
goto again;
+ }
KASSERT((p->flags & PG_FICTITIOUS) == 0,
("vm_object_page_remove: page %p is fictitious", p));
if ((options & OBJPR_CLEANONLY) != 0 && p->valid != 0) {
Modified: user/attilio/vmobj-readlock/sys/vm/vm_page.c
==============================================================================
--- user/attilio/vmobj-readlock/sys/vm/vm_page.c Mon May 27 15:51:03 2013 (r251028)
+++ user/attilio/vmobj-readlock/sys/vm/vm_page.c Mon May 27 16:12:39 2013 (r251029)
@@ -784,17 +784,19 @@ _vm_page_sleep_onpage(vm_page_t m, int p
*
* Sleep and release the page queues lock if VPO_BUSY is set or,
* if also_m_busy is TRUE, busy is non-zero. Returns TRUE if the
- * thread slept and the page queues lock was released.
- * Otherwise, retains the page queues lock and returns FALSE.
+ * thread slept.
*
- * The given page and object containing it must be locked.
+ * The given page must be unlocked and object containing it must
+ * be locked.
*/
int
vm_page_sleep_if_busy(vm_page_t m, const char *msg)
{
vm_object_t obj;
+ vm_page_lock_assert(m, MA_NOTOWNED);
VM_OBJECT_ASSERT_WLOCKED(m->object);
+
if ((m->oflags & VPO_BUSY) != 0 || m->busy != 0) {
/*
* The page-specific object must be cached because page
@@ -804,6 +806,7 @@ vm_page_sleep_if_busy(vm_page_t m, const
* held by the callers.
*/
obj = m->object;
+ vm_page_lock(m);
VM_OBJECT_WUNLOCK(obj);
_vm_page_sleep_onpage(m, PVM, msg, 0);
VM_OBJECT_WLOCK(obj);
More information about the svn-src-user
mailing list