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 | |
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
-rw-r--r-- | sys/vm/vm_contig.c | 9 | ||||
-rw-r--r-- | sys/vm/vm_pageout.c | 2 | ||||
-rw-r--r-- | 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 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) diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index d21277b..f5d4ee7 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 1b74fab..1586ac4 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_ */ |