Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern fix a lock order reversal during global boundary ta...



details:   https://anonhg.NetBSD.org/src/rev/0afb85f5009e
branches:  trunk
changeset: 783695:0afb85f5009e
user:      para <para%NetBSD.org@localhost>
date:      Fri Jan 04 08:28:38 2013 +0000

description:
fix a lock order reversal during global boundary tag refill.
thanks to chuq@
xxx: request pullup

diffstat:

 sys/kern/subr_vmem.c |  28 ++++++++++++++++++++++------
 1 files changed, 22 insertions(+), 6 deletions(-)

diffs (90 lines):

diff -r b4fcbf001b90 -r 0afb85f5009e sys/kern/subr_vmem.c
--- a/sys/kern/subr_vmem.c      Fri Jan 04 07:27:57 2013 +0000
+++ b/sys/kern/subr_vmem.c      Fri Jan 04 08:28:38 2013 +0000
@@ -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 @@
 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_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 @@
        }
        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_t *bt;
 
-       bt_refillglobal(flags);
+       if (!(flags & VM_POPULATING)) {
+               bt_refillglobal(flags);
+       }
 
        VMEM_LOCK(vm);
        mutex_enter(&vmem_btag_lock);
@@ -701,6 +716,7 @@
 {
 
        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) {



Home | Main Index | Thread Index | Old Index