diff options
author | alc <alc@FreeBSD.org> | 2003-05-04 06:56:27 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2003-05-04 06:56:27 +0000 |
commit | 0f78bf82bab85c14dad9daf7cfb00df42163568c (patch) | |
tree | 344a330d99d7d97644afa8b9a62d5497144dd2d9 /sys | |
parent | 24d926fd08e74922d40e806e13cb2624dfe2eafd (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/vm/vm_pageout.c | 16 |
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); } /* |