summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_contig.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2007-11-25 20:37:29 +0000
committeralc <alc@FreeBSD.org>2007-11-25 20:37:29 +0000
commit625e38eddc8b523d10948382f838410bcea38748 (patch)
tree364366c6cc52df834ec3c2828985b5fef1a6d111 /sys/vm/vm_contig.c
parentfe29db8e3b4c220b99a7cb801aa9de3d1db113a4 (diff)
downloadFreeBSD-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.c9
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)
OpenPOWER on IntegriCloud