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_ */