From 625e38eddc8b523d10948382f838410bcea38748 Mon Sep 17 00:00:00 2001 From: alc Date: Sun, 25 Nov 2007 20:37:29 +0000 Subject: [PATCH] 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 --- sys/vm/vm_contig.c | 9 ++++++--- sys/vm/vm_pageout.c | 2 +- sys/vm/vm_pageout.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c index 7a6eb5130436..1458e0d8d2f8 100644 --- a/sys/vm/vm_contig.c +++ b/sys/vm/vm_contig.c @@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$"); #include 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) diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index d21277b51f4d..f5d4ee7adee4 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -230,7 +230,7 @@ static void vm_pageout_page_stats(void); * This function depends on both the lock portion of struct vm_object * and normal struct vm_page being type stable. */ -static boolean_t +boolean_t vm_pageout_fallback_object_lock(vm_page_t m, vm_page_t *next) { struct vm_page marker; diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h index 1b74fab74f0e..1586ac41475d 100644 --- a/sys/vm/vm_pageout.h +++ b/sys/vm/vm_pageout.h @@ -98,6 +98,7 @@ extern void vm_wait(void); extern void vm_waitpfault(void); #ifdef _KERNEL +boolean_t vm_pageout_fallback_object_lock(vm_page_t, vm_page_t *); int vm_pageout_flush(vm_page_t *, int, int); #endif #endif /* _VM_VM_PAGEOUT_H_ */