diff options
author | alc <alc@FreeBSD.org> | 2007-11-25 20:37:29 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2007-11-25 20:37:29 +0000 |
commit | 625e38eddc8b523d10948382f838410bcea38748 (patch) | |
tree | 364366c6cc52df834ec3c2828985b5fef1a6d111 /sys/vm/vm_contig.c | |
parent | fe29db8e3b4c220b99a7cb801aa9de3d1db113a4 (diff) | |
download | FreeBSD-src-625e38eddc8b523d10948382f838410bcea38748.zip FreeBSD-src-625e38eddc8b523d10948382f838410bcea38748.tar.gz |
Make contigmalloc(9)'s page laundering more robust. Specifically, use
vm_pageout_fallback_object_lock() in vm_contig_launder_page() to better
handle a lock-ordering problem. Consequently, trylock's failure on the
page's containing object no longer implies that the page cannot be
laundered.
MFC after: 6 weeks
Diffstat (limited to 'sys/vm/vm_contig.c')
-rw-r--r-- | sys/vm/vm_contig.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c index 7a6eb51..1458e0d 100644 --- a/sys/vm/vm_contig.c +++ b/sys/vm/vm_contig.c @@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_extern.h> static int -vm_contig_launder_page(vm_page_t m) +vm_contig_launder_page(vm_page_t m, vm_page_t *next) { vm_object_t object; vm_page_t m_tmp; @@ -98,8 +98,11 @@ vm_contig_launder_page(vm_page_t m) mtx_assert(&vm_page_queue_mtx, MA_OWNED); object = m->object; - if (!VM_OBJECT_TRYLOCK(object)) + if (!VM_OBJECT_TRYLOCK(object) && + !vm_pageout_fallback_object_lock(m, next)) { + VM_OBJECT_UNLOCK(object); return (EAGAIN); + } if (vm_page_sleep_if_busy(m, TRUE, "vpctw0")) { VM_OBJECT_UNLOCK(object); vm_page_lock_queues(); @@ -157,7 +160,7 @@ vm_contig_launder(int queue) KASSERT(VM_PAGE_INQUEUE2(m, queue), ("vm_contig_launder: page %p's queue is not %d", m, queue)); - error = vm_contig_launder_page(m); + error = vm_contig_launder_page(m, &next); if (error == 0) return (TRUE); if (error == EBUSY) |