Source-Changes-HG archive

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

[src/trunk]: src/sys - Make KMGUARD interrupt-safe.



details:   https://anonhg.NetBSD.org/src/rev/6683bc7122f5
branches:  trunk
changeset: 773530:6683bc7122f5
user:      rmind <rmind%NetBSD.org@localhost>
date:      Sun Feb 05 03:40:07 2012 +0000

description:
- Make KMGUARD interrupt-safe.
- kmem_intr_{alloc,free}: remove workaround.

Changes affect KMGUARD-enabled debug kernels only.

diffstat:

 sys/kern/subr_kmem.c  |  12 +++++-------
 sys/sys/kmem.h        |   4 ++--
 sys/uvm/uvm_kmguard.c |  36 ++++++++++++++----------------------
 sys/uvm/uvm_kmguard.h |  15 +++++++--------
 4 files changed, 28 insertions(+), 39 deletions(-)

diffs (219 lines):

diff -r 6c6f35cc2bc9 -r 6683bc7122f5 sys/kern/subr_kmem.c
--- a/sys/kern/subr_kmem.c      Sun Feb 05 00:41:15 2012 +0000
+++ b/sys/kern/subr_kmem.c      Sun Feb 05 03:40:07 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: subr_kmem.c,v 1.41 2012/01/30 21:05:40 rmind Exp $     */
+/*     $NetBSD: subr_kmem.c,v 1.42 2012/02/05 03:40:08 rmind Exp $     */
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_kmem.c,v 1.41 2012/01/30 21:05:40 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_kmem.c,v 1.42 2012/02/05 03:40:08 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/callback.h>
@@ -170,8 +170,7 @@
        KASSERT(size > 0);
 
 #ifdef KMEM_GUARD
-       if (size <= kmem_guard_size &&
-           __builtin_return_address(0) == &kmem_alloc) {
+       if (size <= kmem_guard_size) {
                return uvm_kmguard_alloc(&kmem_guard, size,
                    (kmflags & KM_SLEEP) != 0);
        }
@@ -220,8 +219,7 @@
        KASSERT(size > 0);
 
 #ifdef KMEM_GUARD
-       if (size <= kmem_guard_size &&
-           __builtin_return_address(0) == &kmem_free) {
+       if (size <= kmem_guard_size) {
                uvm_kmguard_free(&kmem_guard, size, p);
                return;
        }
@@ -344,7 +342,7 @@
 
 #ifdef KMEM_GUARD
        uvm_kmguard_init(&kmem_guard, &kmem_guard_depth, &kmem_guard_size,
-               kernel_map);
+           kmem_va_arena);
 #endif
        kmem_create_caches(kmem_cache_sizes, kmem_cache, KMEM_MAXSIZE);
 }
diff -r 6c6f35cc2bc9 -r 6683bc7122f5 sys/sys/kmem.h
--- a/sys/sys/kmem.h    Sun Feb 05 00:41:15 2012 +0000
+++ b/sys/sys/kmem.h    Sun Feb 05 03:40:07 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kmem.h,v 1.8 2012/01/28 23:09:07 rmind Exp $   */
+/*     $NetBSD: kmem.h,v 1.9 2012/02/05 03:40:08 rmind Exp $   */
 
 /*-
  * Copyright (c)2006 YAMAMOTO Takashi,
@@ -42,7 +42,7 @@
 
 void * kmem_intr_alloc(size_t, km_flag_t);
 void * kmem_intr_zalloc(size_t, km_flag_t);
-void   kmem_intr_free(void *, size_t size);
+void   kmem_intr_free(void *, size_t);
 
 char * kmem_asprintf(const char *, ...) __printflike(1, 2);
 
diff -r 6c6f35cc2bc9 -r 6683bc7122f5 sys/uvm/uvm_kmguard.c
--- a/sys/uvm/uvm_kmguard.c     Sun Feb 05 00:41:15 2012 +0000
+++ b/sys/uvm/uvm_kmguard.c     Sun Feb 05 03:40:07 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_kmguard.c,v 1.7 2012/01/28 00:00:06 rmind Exp $    */
+/*     $NetBSD: uvm_kmguard.c,v 1.8 2012/02/05 03:40:07 rmind Exp $    */
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -37,8 +37,9 @@
  * - Invalid pointer/size passed, at free
  * - Use-after-free
  */
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_kmguard.c,v 1.7 2012/01/28 00:00:06 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_kmguard.c,v 1.8 2012/02/05 03:40:07 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,8 +53,7 @@
 #define        MAXSIZE                 (PAGE_SIZE - sizeof(void *))
 
 void
-uvm_kmguard_init(struct uvm_kmguard *kg, u_int *depth, size_t *size,
-                struct vm_map *map)
+uvm_kmguard_init(struct uvm_kmguard *kg, u_int *depth, size_t *size, vmem_t *vm)
 {
        vaddr_t va;
 
@@ -67,7 +67,7 @@
        *depth = roundup((*depth), PAGE_SIZE / sizeof(void *));
        KASSERT(*depth != 0);
 
-       /*      
+       /*
         * allocate fifo.
         */
 
@@ -84,7 +84,7 @@
         * init object.
         */
 
-       kg->kg_map = map;
+       kg->kg_vmem = vm;
        kg->kg_fifo = (void *)va;
        kg->kg_depth = *depth;
        kg->kg_rotor = 0;
@@ -96,9 +96,9 @@
 uvm_kmguard_alloc(struct uvm_kmguard *kg, size_t len, bool waitok)
 {
        struct vm_page *pg;
+       vm_flag_t flags;
        void **p;
        vaddr_t va;
-       int flag;
 
        /*
         * can't handle >PAGE_SIZE allocations.  let the caller handle it
@@ -113,15 +113,8 @@
         * allocate two pages of kernel VA, but do not map anything in yet.
         */
 
-       if (waitok) {
-               flag = UVM_KMF_WAITVA;
-       } else {
-               flag = UVM_KMF_TRYLOCK | UVM_KMF_NOWAIT;
-       }
-       va = vm_map_min(kg->kg_map);
-       if (__predict_false(uvm_map(kg->kg_map, &va, PAGE_SIZE*2, NULL,
-           UVM_UNKNOWN_OFFSET, PAGE_SIZE, UVM_MAPFLAG(UVM_PROT_ALL,
-           UVM_PROT_ALL, UVM_INH_NONE, UVM_ADV_RANDOM, flag)) != 0)) {
+       flags = VM_BESTFIT | (waitok ? VM_SLEEP : VM_NOSLEEP);
+       if (vmem_alloc(kg->kg_vmem, PAGE_SIZE * 2, flags, &va) != 0) {
                return NULL;
        }
 
@@ -131,7 +124,7 @@
         */
 
        for (;;) {
-               pg = uvm_pagealloc(NULL, va - vm_map_min(kg->kg_map), NULL, 0);
+               pg = uvm_pagealloc(NULL, va, NULL, 0);
                if (__predict_true(pg != NULL)) {
                        break;
                }
@@ -139,8 +132,7 @@
                        uvm_wait("kmguard");    /* sleep here */
                        continue;
                } else {
-                       uvm_km_free(kg->kg_map, va, PAGE_SIZE*2,
-                           UVM_KMF_VAONLY);
+                       vmem_free(kg->kg_vmem, va, PAGE_SIZE * 2);
                        return NULL;
                }
        }
@@ -157,7 +149,7 @@
 
        p = (void **)((va + PAGE_SIZE - len) & ~(uintptr_t)ALIGNBYTES);
        p[-1] = CANARY(va, len);
-       return (void *)p; 
+       return (void *)p;
 }
 
 bool
@@ -187,7 +179,7 @@
         * allocated .
         */
 
-       uvm_km_pgremove_intrsafe(kg->kg_map, va, va + PAGE_SIZE * 2);
+       uvm_km_pgremove_intrsafe(kernel_map, va, va + PAGE_SIZE * 2);
        pmap_kremove(va, PAGE_SIZE * 2);
        pmap_update(pmap_kernel());
 
@@ -199,7 +191,7 @@
        rotor = atomic_inc_uint_nv(&kg->kg_rotor) % kg->kg_depth;
        va = (vaddr_t)atomic_swap_ptr(&kg->kg_fifo[rotor], (void *)va);
        if (va != 0) {
-               uvm_km_free(kg->kg_map, va, PAGE_SIZE*2, UVM_KMF_VAONLY);
+               vmem_free(kg->kg_vmem, va, PAGE_SIZE * 2);
        }
 
        return true;
diff -r 6c6f35cc2bc9 -r 6683bc7122f5 sys/uvm/uvm_kmguard.h
--- a/sys/uvm/uvm_kmguard.h     Sun Feb 05 00:41:15 2012 +0000
+++ b/sys/uvm/uvm_kmguard.h     Sun Feb 05 03:40:07 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_kmguard.h,v 1.1 2009/03/29 10:51:53 ad Exp $       */
+/*     $NetBSD: uvm_kmguard.h,v 1.2 2012/02/05 03:40:07 rmind Exp $    */
 
 /*-
  * Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -33,15 +33,14 @@
 #define        _UVM_KMGUARD_H_
 
 struct uvm_kmguard {
-       u_int   kg_depth;
-       intptr_t *kg_fifo;
-       u_int   kg_rotor;
-       struct  vm_map *kg_map;
+       u_int           kg_depth;
+       intptr_t *      kg_fifo;
+       u_int           kg_rotor;
+       vmem_t *        kg_vmem;
 };
 
-void   uvm_kmguard_init(struct uvm_kmguard *, u_int *, size_t *,
-                        struct vm_map *);
-void   *uvm_kmguard_alloc(struct uvm_kmguard *, size_t, bool);
+void   uvm_kmguard_init(struct uvm_kmguard *, u_int *, size_t *, vmem_t *);
+void * uvm_kmguard_alloc(struct uvm_kmguard *, size_t, bool);
 bool   uvm_kmguard_free(struct uvm_kmguard *, size_t, void *);
 
 #endif /* _UVM_KMGUARD_H_ */



Home | Main Index | Thread Index | Old Index