fix a lock order reversal during global boundary tag refill.
thanks to chuq@ xxx: request pullup
This commit is contained in:
parent
e17e68c7fd
commit
493b8304e5
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr_vmem.c,v 1.76 2012/09/13 21:44:50 joerg Exp $ */
|
||||
/* $NetBSD: subr_vmem.c,v 1.77 2013/01/04 08:28:38 para Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c)2006,2007,2008,2009 YAMAMOTO Takashi,
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.76 2012/09/13 21:44:50 joerg Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.77 2013/01/04 08:28:38 para Exp $");
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#include "opt_ddb.h"
|
||||
|
@ -273,6 +273,7 @@ static int static_qc_pool_count = STATIC_QC_POOL_COUNT;
|
|||
vmem_t *kmem_va_meta_arena;
|
||||
vmem_t *kmem_meta_arena;
|
||||
|
||||
static kmutex_t vmem_refill_lock;
|
||||
static kmutex_t vmem_btag_lock;
|
||||
static LIST_HEAD(, vmem_btag) vmem_btag_freelist;
|
||||
static size_t vmem_btag_freelist_count = 0;
|
||||
|
@ -292,19 +293,26 @@ bt_refillglobal(vm_flag_t flags)
|
|||
bt_t *bt;
|
||||
int i;
|
||||
|
||||
mutex_enter(&vmem_refill_lock);
|
||||
|
||||
mutex_enter(&vmem_btag_lock);
|
||||
if (vmem_btag_freelist_count > 0) {
|
||||
mutex_exit(&vmem_btag_lock);
|
||||
mutex_exit(&vmem_refill_lock);
|
||||
return 0;
|
||||
} else {
|
||||
mutex_exit(&vmem_btag_lock);
|
||||
}
|
||||
|
||||
if (vmem_alloc(kmem_meta_arena, PAGE_SIZE,
|
||||
(flags & ~VM_FITMASK) | VM_INSTANTFIT | VM_POPULATING, &va) != 0) {
|
||||
mutex_exit(&vmem_btag_lock);
|
||||
mutex_exit(&vmem_refill_lock);
|
||||
return ENOMEM;
|
||||
}
|
||||
VMEM_EVCNT_INCR(bt_pages);
|
||||
|
||||
mutex_enter(&vmem_btag_lock);
|
||||
btp = (void *) va;
|
||||
for (i = 0; i < (BT_PER_PAGE); i++) {
|
||||
bt = btp;
|
||||
|
@ -318,9 +326,14 @@ bt_refillglobal(vm_flag_t flags)
|
|||
}
|
||||
mutex_exit(&vmem_btag_lock);
|
||||
|
||||
bt_refill(kmem_arena, (flags & ~VM_FITMASK) | VM_INSTANTFIT);
|
||||
bt_refill(kmem_va_meta_arena, (flags & ~VM_FITMASK) | VM_INSTANTFIT);
|
||||
bt_refill(kmem_meta_arena, (flags & ~VM_FITMASK) | VM_INSTANTFIT);
|
||||
bt_refill(kmem_arena, (flags & ~VM_FITMASK)
|
||||
| VM_INSTANTFIT | VM_POPULATING);
|
||||
bt_refill(kmem_va_meta_arena, (flags & ~VM_FITMASK)
|
||||
| VM_INSTANTFIT | VM_POPULATING);
|
||||
bt_refill(kmem_meta_arena, (flags & ~VM_FITMASK)
|
||||
| VM_INSTANTFIT | VM_POPULATING);
|
||||
|
||||
mutex_exit(&vmem_refill_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -330,7 +343,9 @@ bt_refill(vmem_t *vm, vm_flag_t flags)
|
|||
{
|
||||
bt_t *bt;
|
||||
|
||||
bt_refillglobal(flags);
|
||||
if (!(flags & VM_POPULATING)) {
|
||||
bt_refillglobal(flags);
|
||||
}
|
||||
|
||||
VMEM_LOCK(vm);
|
||||
mutex_enter(&vmem_btag_lock);
|
||||
|
@ -701,6 +716,7 @@ vmem_bootstrap(void)
|
|||
{
|
||||
|
||||
mutex_init(&vmem_list_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
mutex_init(&vmem_refill_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
mutex_init(&vmem_btag_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
|
||||
while (static_bt_count-- > 0) {
|
||||
|
|
Loading…
Reference in New Issue