svn commit: r207450 - head/sys/vm
Kip Macy
kmacy at FreeBSD.org
Fri Apr 30 21:20:15 UTC 2010
Author: kmacy
Date: Fri Apr 30 21:20:14 2010
New Revision: 207450
URL: http://svn.freebsd.org/changeset/base/207450
Log:
- acquire the page lock in vm_contig_launder_page before checking page fields
- release page queue lock before calling vm_pageout_flush
Modified:
head/sys/vm/vm_contig.c
Modified: head/sys/vm/vm_contig.c
==============================================================================
--- head/sys/vm/vm_contig.c Fri Apr 30 19:52:35 2010 (r207449)
+++ head/sys/vm/vm_contig.c Fri Apr 30 21:20:14 2010 (r207450)
@@ -96,30 +96,33 @@ vm_contig_launder_page(vm_page_t m, vm_p
vm_page_t m_tmp;
struct vnode *vp;
struct mount *mp;
- int vfslocked;
+ int vfslocked, dirty;
- mtx_assert(&vm_page_queue_mtx, MA_OWNED);
+ vm_page_lock(m);
+ vm_page_lock_queues();
object = m->object;
if (!VM_OBJECT_TRYLOCK(object) &&
!vm_pageout_fallback_object_lock(m, next)) {
VM_OBJECT_UNLOCK(object);
+ vm_page_unlock_queues();
+ vm_page_unlock(m);
return (EAGAIN);
}
if (vm_page_sleep_if_busy(m, TRUE, "vpctw0")) {
VM_OBJECT_UNLOCK(object);
- vm_page_lock_queues();
return (EBUSY);
}
vm_page_test_dirty(m);
if (m->dirty == 0 && m->hold_count == 0)
pmap_remove_all(m);
- if (m->dirty) {
+ if ((dirty = m->dirty) != 0) {
+ vm_page_unlock_queues();
+ vm_page_unlock(m);
if ((object->flags & OBJ_DEAD) != 0) {
VM_OBJECT_UNLOCK(object);
return (EAGAIN);
}
if (object->type == OBJT_VNODE) {
- vm_page_unlock_queues();
vp = object->handle;
vm_object_reference_locked(object);
VM_OBJECT_UNLOCK(object);
@@ -133,7 +136,6 @@ vm_contig_launder_page(vm_page_t m, vm_p
VFS_UNLOCK_GIANT(vfslocked);
vm_object_deallocate(object);
vn_finished_write(mp);
- vm_page_lock_queues();
return (0);
} else if (object->type == OBJT_SWAP ||
object->type == OBJT_DEFAULT) {
@@ -144,6 +146,11 @@ vm_contig_launder_page(vm_page_t m, vm_p
}
} else if (m->hold_count == 0)
vm_page_cache(m);
+
+ if (dirty == 0) {
+ vm_page_unlock_queues();
+ vm_page_unlock(m);
+ }
VM_OBJECT_UNLOCK(object);
return (0);
}
@@ -162,7 +169,9 @@ vm_contig_launder(int queue)
KASSERT(VM_PAGE_INQUEUE2(m, queue),
("vm_contig_launder: page %p's queue is not %d", m, queue));
+ vm_page_unlock_queues();
error = vm_contig_launder_page(m, &next);
+ vm_page_lock_queues();
if (error == 0)
return (TRUE);
if (error == EBUSY)
More information about the svn-src-all
mailing list