summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-03-02 08:25:58 +0000
committeralc <alc@FreeBSD.org>2004-03-02 08:25:58 +0000
commit163a9eabd15682886036ee17e7bf50276cfadc44 (patch)
treeef9bbcfe7b4b5242299d8ccd4cc46be20dac0bb7
parent1ae35df34955572c1479f39a97b240244c97cc44 (diff)
downloadFreeBSD-src-163a9eabd15682886036ee17e7bf50276cfadc44.zip
FreeBSD-src-163a9eabd15682886036ee17e7bf50276cfadc44.tar.gz
Modify contigmalloc1() so that the free page queues lock is not held when
vm_page_free() is called. The problem with holding this lock is that it is a spin lock and vm_page_free() may attempt the acquisition of a different default-type lock.
-rw-r--r--sys/vm/vm_contig.c14
-rw-r--r--sys/vm/vm_page.c5
2 files changed, 15 insertions, 4 deletions
diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c
index 311a87a..bc78dd0 100644
--- a/sys/vm/vm_contig.c
+++ b/sys/vm/vm_contig.c
@@ -169,6 +169,7 @@ contigmalloc1(
start = 0;
for (pass = 0; pass <= 1; pass++) {
vm_page_lock_queues();
+again0:
mtx_lock_spin(&vm_page_queue_free_mtx);
again:
/*
@@ -213,6 +214,7 @@ again1:
goto again;
}
}
+ mtx_unlock_spin(&vm_page_queue_free_mtx);
for (i = start; i < (start + size / PAGE_SIZE); i++) {
vm_page_t m = &pga[i];
@@ -220,13 +222,23 @@ again1:
object = m->object;
if (!VM_OBJECT_TRYLOCK(object)) {
start++;
- goto again;
+ goto again0;
}
vm_page_busy(m);
vm_page_free(m);
VM_OBJECT_UNLOCK(object);
}
}
+ mtx_lock_spin(&vm_page_queue_free_mtx);
+ for (i = start; i < (start + size / PAGE_SIZE); i++) {
+ pqtype = pga[i].queue - pga[i].pc;
+ if ((VM_PAGE_TO_PHYS(&pga[i]) !=
+ (VM_PAGE_TO_PHYS(&pga[i - 1]) + PAGE_SIZE)) ||
+ (pqtype != PQ_FREE)) {
+ start++;
+ goto again;
+ }
+ }
for (i = start; i < (start + size / PAGE_SIZE); i++) {
vm_page_t m = &pga[i];
vm_pageq_remove_nowakeup(m);
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 853178a..ae1673a 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -206,12 +206,11 @@ vm_page_startup(vm_offset_t starta, vm_offset_t enda, vm_offset_t vaddr)
end = phys_avail[biggestone+1];
/*
- * Initialize the locks. Recursive acquisition of the vm page
- * queue free mutex begins in contigmalloc1().
+ * Initialize the locks.
*/
mtx_init(&vm_page_queue_mtx, "vm page queue mutex", NULL, MTX_DEF);
mtx_init(&vm_page_queue_free_mtx, "vm page queue free mutex", NULL,
- MTX_RECURSE | MTX_SPIN);
+ MTX_SPIN);
/*
* Initialize the queue headers for the free queue, the active queue
OpenPOWER on IntegriCloud