Module Name:    src
Committed By:   rmind
Date:           Sun Feb  5 03:40:08 UTC 2012

Modified Files:
        src/sys/kern: subr_kmem.c
        src/sys/sys: kmem.h
        src/sys/uvm: uvm_kmguard.c uvm_kmguard.h

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

Changes affect KMGUARD-enabled debug kernels only.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/sys/kern/subr_kmem.c
cvs rdiff -u -r1.8 -r1.9 src/sys/sys/kmem.h
cvs rdiff -u -r1.7 -r1.8 src/sys/uvm/uvm_kmguard.c
cvs rdiff -u -r1.1 -r1.2 src/sys/uvm/uvm_kmguard.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/subr_kmem.c
diff -u src/sys/kern/subr_kmem.c:1.41 src/sys/kern/subr_kmem.c:1.42
--- src/sys/kern/subr_kmem.c:1.41	Mon Jan 30 21:05:40 2012
+++ src/sys/kern/subr_kmem.c	Sun Feb  5 03:40:08 2012
@@ -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 @@ kmem_intr_alloc(size_t size, km_flag_t k
 	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 @@ kmem_intr_free(void *p, size_t size)
 	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 @@ kmem_init(void)
 
 #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);
 }

Index: src/sys/sys/kmem.h
diff -u src/sys/sys/kmem.h:1.8 src/sys/sys/kmem.h:1.9
--- src/sys/sys/kmem.h:1.8	Sat Jan 28 23:09:07 2012
+++ src/sys/sys/kmem.h	Sun Feb  5 03:40:08 2012
@@ -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_free(void *, size_t);
 
 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);
 

Index: src/sys/uvm/uvm_kmguard.c
diff -u src/sys/uvm/uvm_kmguard.c:1.7 src/sys/uvm/uvm_kmguard.c:1.8
--- src/sys/uvm/uvm_kmguard.c:1.7	Sat Jan 28 00:00:06 2012
+++ src/sys/uvm/uvm_kmguard.c	Sun Feb  5 03:40:07 2012
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_kmguard.
 #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 @@ uvm_kmguard_init(struct uvm_kmguard *kg,
 	*depth = roundup((*depth), PAGE_SIZE / sizeof(void *));
 	KASSERT(*depth != 0);
 
-	/*	
+	/*
 	 * allocate fifo.
 	 */
 
@@ -84,7 +84,7 @@ uvm_kmguard_init(struct uvm_kmguard *kg,
 	 * 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 @@ void *
 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 @@ uvm_kmguard_alloc(struct uvm_kmguard *kg
 	 * 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 @@ uvm_kmguard_alloc(struct uvm_kmguard *kg
 	 */
 
 	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_kmguard_alloc(struct uvm_kmguard *kg
 			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 @@ uvm_kmguard_alloc(struct uvm_kmguard *kg
 
 	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 @@ uvm_kmguard_free(struct uvm_kmguard *kg,
 	 * 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 @@ uvm_kmguard_free(struct uvm_kmguard *kg,
 	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;

Index: src/sys/uvm/uvm_kmguard.h
diff -u src/sys/uvm/uvm_kmguard.h:1.1 src/sys/uvm/uvm_kmguard.h:1.2
--- src/sys/uvm/uvm_kmguard.h:1.1	Sun Mar 29 10:51:53 2009
+++ src/sys/uvm/uvm_kmguard.h	Sun Feb  5 03:40:07 2012
@@ -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_ */

Reply via email to