summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_pageout.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-05-04 06:56:27 +0000
committeralc <alc@FreeBSD.org>2003-05-04 06:56:27 +0000
commit0f78bf82bab85c14dad9daf7cfb00df42163568c (patch)
tree344a330d99d7d97644afa8b9a62d5497144dd2d9 /sys/vm/vm_pageout.c
parent24d926fd08e74922d40e806e13cb2624dfe2eafd (diff)
downloadFreeBSD-src-0f78bf82bab85c14dad9daf7cfb00df42163568c.zip
FreeBSD-src-0f78bf82bab85c14dad9daf7cfb00df42163568c.tar.gz
Avoid a lock-order reversal and implement vm_object locking
in vm_pageout_page_free().
Diffstat (limited to 'sys/vm/vm_pageout.c')
-rw-r--r--sys/vm/vm_pageout.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index eacbd14..9cfb24c 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -613,25 +613,25 @@ vm_pageout_map_deactivate_pages(map, desired)
#endif /* !defined(NO_SWAPPING) */
/*
- * Don't try to be fancy - being fancy can lead to VOP_LOCK's and therefore
- * to vnode deadlocks. We only do it for OBJT_DEFAULT and OBJT_SWAP objects
- * which we know can be trivially freed.
+ * Warning! The page queue lock is released and reacquired.
*/
static void
vm_pageout_page_free(vm_page_t m)
{
vm_object_t object = m->object;
- int type = object->type;
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
- if (type == OBJT_SWAP || type == OBJT_DEFAULT)
- vm_object_reference(object);
vm_page_busy(m);
+ vm_page_unlock_queues();
+ /*
+ * Avoid a lock order reversal. The page must be busy.
+ */
+ VM_OBJECT_LOCK(object);
+ vm_page_lock_queues();
pmap_remove_all(m);
vm_page_free(m);
+ VM_OBJECT_UNLOCK(object);
cnt.v_dfree++;
- if (type == OBJT_SWAP || type == OBJT_DEFAULT)
- vm_object_deallocate(object);
}
/*
OpenPOWER on IntegriCloud