diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2011-04-04 11:13:56 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2011-04-04 11:13:56 +0000 |
commit | 750668c1f913b914d8a963efd94b868662f69102 (patch) | |
tree | aff1e2fa8b787001204f7d8b2d864e543d267ba4 /sys | |
parent | 034c18b1fa0532c3bfd9a8f4af7d6e7ba3512536 (diff) |
sysctl kern.pool_debug=0 will disable POOL_DEBUG on the fly (still defaults
to on, if POOL_DEBUG is compiled in, so that boot-time pool corruption
can be found. When the sysctl is turned off, performance is almost as
as good as compiling with POOL_DEBUG compiled out. Not all pool page
headers can be purged of the magic checks.
performance tests by henning
ok ariane kettenis mikeb
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_sysctl.c | 12 | ||||
-rw-r--r-- | sys/kern/subr_pool.c | 64 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 6 |
3 files changed, 55 insertions, 27 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index a2536b7a297..2ac85792d08 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.199 2011/04/02 16:47:17 beck Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.200 2011/04/04 11:13:55 deraadt Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -270,6 +270,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, extern int cryptodevallowsoft; #endif extern int maxlocksperuid; + extern int pool_debug; /* all sysctl names at this level are terminal except a ton of them */ if (namelen != 1) { @@ -591,6 +592,15 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev)); case KERN_NETLIVELOCKS: return (sysctl_rdint(oldp, oldlenp, newp, mcllivelocks)); + case KERN_POOL_DEBUG: { + int old_pool_debug = pool_debug; + + error = sysctl_int(oldp, oldlenp, newp, newlen, + &pool_debug); + if (error == 0 && pool_debug != old_pool_debug) + pool_reclaim_all(); + return (error); + } default: return (EOPNOTSUPP); } diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c index c7d85ff0f23..345544b4f04 100644 --- a/sys/kern/subr_pool.c +++ b/sys/kern/subr_pool.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_pool.c,v 1.100 2011/04/03 22:07:37 ariane Exp $ */ +/* $OpenBSD: subr_pool.c,v 1.101 2011/04/04 11:13:55 deraadt Exp $ */ /* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */ /*- @@ -42,7 +42,7 @@ #include <sys/sysctl.h> #include <uvm/uvm.h> - +#include <dev/rndvar.h> /* * Pool resource management utility. @@ -74,6 +74,7 @@ struct pool_item_header { caddr_t ph_page; /* this page's address */ caddr_t ph_colored; /* page's colored address */ int ph_pagesize; + int ph_magic; }; struct pool_item { @@ -90,6 +91,12 @@ struct pool_item { #define PI_MAGIC 0xdeafbeef #endif +#ifdef POOL_DEBUG +int pool_debug = 1; +#else +int pool_debug = 0; +#endif + #define POOL_NEEDS_CATCHUP(pp) \ ((pp)->pr_nitems < (pp)->pr_minitems) @@ -441,7 +448,8 @@ pool_alloc_item_header(struct pool *pp, caddr_t storage, int flags) else ph = pool_get(&phpool, (flags & ~(PR_WAITOK | PR_ZERO)) | PR_NOWAIT); - + if (pool_debug) + ph->ph_magic = PI_MAGIC; return (ph); } @@ -611,13 +619,15 @@ startover: "page %p; item addr %p; offset 0x%x=0x%x", pp->pr_wchan, ph->ph_page, pi, 0, pi->pi_magic); #ifdef POOL_DEBUG - for (ip = (int *)pi, i = sizeof(*pi) / sizeof(int); - i < pp->pr_size / sizeof(int); i++) { - if (ip[i] != PI_MAGIC) { - panic("pool_do_get(%s): free list modified: " - "page %p; item addr %p; offset 0x%x=0x%x", - pp->pr_wchan, ph->ph_page, pi, - i * sizeof(int), ip[i]); + if (pool_debug && ph->ph_magic) { + for (ip = (int *)pi, i = sizeof(*pi) / sizeof(int); + i < pp->pr_size / sizeof(int); i++) { + if (ip[i] != ph->ph_magic) { + panic("pool_do_get(%s): free list modified: " + "page %p; item addr %p; offset 0x%x=0x%x", + pp->pr_wchan, ph->ph_page, pi, + i * sizeof(int), ip[i]); + } } } #endif /* POOL_DEBUG */ @@ -731,9 +741,11 @@ pool_do_put(struct pool *pp, void *v) #ifdef DIAGNOSTIC pi->pi_magic = PI_MAGIC; #ifdef POOL_DEBUG - for (ip = (int *)pi, i = sizeof(*pi)/sizeof(int); - i < pp->pr_size / sizeof(int); i++) - ip[i] = PI_MAGIC; + if (ph->ph_magic) { + for (ip = (int *)pi, i = sizeof(*pi)/sizeof(int); + i < pp->pr_size / sizeof(int); i++) + ip[i] = ph->ph_magic; + } #endif /* POOL_DEBUG */ #endif /* DIAGNOSTIC */ @@ -886,9 +898,11 @@ pool_prime_page(struct pool *pp, caddr_t storage, struct pool_item_header *ph) #ifdef DIAGNOSTIC pi->pi_magic = PI_MAGIC; #ifdef POOL_DEBUG - for (ip = (int *)pi, i = sizeof(*pi)/sizeof(int); - i < pp->pr_size / sizeof(int); i++) - ip[i] = PI_MAGIC; + if (ph->ph_magic) { + for (ip = (int *)pi, i = sizeof(*pi)/sizeof(int); + i < pp->pr_size / sizeof(int); i++) + ip[i] = ph->ph_magic; + } #endif /* POOL_DEBUG */ #endif /* DIAGNOSTIC */ cp = (caddr_t)(cp + pp->pr_size); @@ -1273,14 +1287,16 @@ pool_chk_page(struct pool *pp, const char *label, struct pool_item_header *ph) 0, pi->pi_magic); } #ifdef POOL_DEBUG - for (ip = (int *)pi, i = sizeof(*pi) / sizeof(int); - i < pp->pr_size / sizeof(int); i++) { - if (ip[i] != PI_MAGIC) { - printf("pool(%s): free list modified: " - "page %p; item ordinal %d; addr %p " - "(p %p); offset 0x%x=0x%x\n", - pp->pr_wchan, ph->ph_page, n, pi, - page, i * sizeof(int), ip[i]); + if (pool_debug && ph->ph_magic) { + for (ip = (int *)pi, i = sizeof(*pi) / sizeof(int); + i < pp->pr_size / sizeof(int); i++) { + if (ip[i] != ph->ph_magic) { + printf("pool(%s): free list modified: " + "page %p; item ordinal %d; addr %p " + "(p %p); offset 0x%x=0x%x\n", + pp->pr_wchan, ph->ph_page, n, pi, + page, i * sizeof(int), ip[i]); + } } } diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 346b33a36b8..5de3000f636 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.109 2011/03/12 04:54:28 guenther Exp $ */ +/* $OpenBSD: sysctl.h,v 1.110 2011/04/04 11:13:53 deraadt Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -188,7 +188,8 @@ struct ctlname { #define KERN_RTHREADS 74 /* kernel rthreads support enabled */ #define KERN_CONSDEV 75 /* dev_t: console terminal device */ #define KERN_NETLIVELOCKS 76 /* int: number of network livelocks */ -#define KERN_MAXID 77 /* number of valid kern ids */ +#define KERN_POOL_DEBUG 77 /* int: enable pool_debug */ +#define KERN_MAXID 78 /* number of valid kern ids */ #define CTL_KERN_NAMES { \ { 0, 0 }, \ @@ -268,6 +269,7 @@ struct ctlname { { "rthreads", CTLTYPE_INT }, \ { "consdev", CTLTYPE_STRUCT }, \ { "netlivelocks", CTLTYPE_INT }, \ + { "pool_debug", CTLTYPE_INT }, \ } /* |