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.
This commit is contained in:
Alan Cox 2004-03-02 08:25:58 +00:00
parent 4daf20b2f1
commit ca3b447732
2 changed files with 15 additions and 4 deletions

View File

@ -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 @@ contigmalloc1(
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 @@ contigmalloc1(
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);

View File

@ -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