diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-02-12 08:06:23 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-02-12 08:06:23 +0000 |
commit | aa4bc9246a0fcaf361cb75d59ca7d19d72962d05 (patch) | |
tree | fc106555772640bd51b2f44ca8966b605ebe3547 /sys/kern | |
parent | 7af426a5b2c56a8f45fc6a4fa8adffb2eab344b4 (diff) |
Back out per-CPU kernel profiling, it shouldn't modify a public header
at this moment.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_clock.c | 6 | ||||
-rw-r--r-- | sys/kern/subr_prof.c | 108 |
2 files changed, 35 insertions, 79 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 57220881f03..d7d51646c2c 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clock.c,v 1.77 2013/02/11 17:05:25 mpi Exp $ */ +/* $OpenBSD: kern_clock.c,v 1.78 2013/02/12 08:06:22 mpi Exp $ */ /* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */ /*- @@ -421,8 +421,8 @@ statclock(struct clockframe *frame) /* * Kernel statistics are just like addupc_intr, only easier. */ - g = ci->ci_gmon; - if (g != NULL && g->state == GMON_PROF_ON) { + g = &_gmonparam; + if (g->state == GMON_PROF_ON) { i = CLKF_PC(frame) - g->lowpc; if (i < g->textsize) { i /= HISTFRACTION * sizeof(*g->kcount); diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index a7eff46dc2f..3786cb11df8 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prof.c,v 1.22 2013/02/11 17:05:25 mpi Exp $ */ +/* $OpenBSD: subr_prof.c,v 1.23 2013/02/12 08:06:22 mpi Exp $ */ /* $NetBSD: subr_prof.c,v 1.12 1996/04/22 01:38:50 christos Exp $ */ /*- @@ -49,75 +49,49 @@ #include <uvm/uvm_extern.h> /* - * Protect CPUs from executing profiling while they are not yet in a - * sane state. + * Froms is actually a bunch of unsigned shorts indexing tos */ -int gmoninit = 0; +struct gmonparam _gmonparam = { GMON_PROF_OFF }; extern char etext[]; -#define ROUNDDOWN(x,y) (((x)/(y))*(y)) -#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) void kmstartup(void) { - CPU_INFO_ITERATOR cii; - struct cpu_info *ci; - struct gmonparam *p; - u_long lowpc, highpc, textsize; - u_long kcountsize, fromssize, tossize; - long tolimit; char *cp; + struct gmonparam *p = &_gmonparam; int size; /* * Round lowpc and highpc to multiples of the density we're using * so the rest of the scaling (here and in gprof) stays in ints. */ - lowpc = ROUNDDOWN(KERNBASE, HISTFRACTION * sizeof(HISTCOUNTER)); - highpc = ROUNDUP((u_long)etext, HISTFRACTION * sizeof(HISTCOUNTER)); - textsize = highpc - lowpc; + p->lowpc = ROUNDDOWN(KERNBASE, HISTFRACTION * sizeof(HISTCOUNTER)); + p->highpc = ROUNDUP((u_long)etext, HISTFRACTION * sizeof(HISTCOUNTER)); + p->textsize = p->highpc - p->lowpc; printf("Profiling kernel, textsize=%ld [%lx..%lx]\n", - textsize, lowpc, highpc); - kcountsize = textsize / HISTFRACTION; - fromssize = textsize / HASHFRACTION; - tolimit = textsize * ARCDENSITY / 100; - if (tolimit < MINARCS) - tolimit = MINARCS; - else if (tolimit > MAXARCS) - tolimit = MAXARCS; - tossize = tolimit * sizeof(struct tostruct); - size = sizeof(*p) + kcountsize + fromssize + tossize; - - /* Allocate and initialize one profiling buffer per CPU. */ - CPU_INFO_FOREACH(cii, ci) { - cp = km_alloc(round_page(size), &kv_any, &kp_zero, &kd_nowait); - if (cp == NULL) { - printf("No memory for profiling.\n"); - return; - } - - p = (struct gmonparam *)cp; - cp += sizeof(*p); - p->tos = (struct tostruct *)cp; - cp += tossize; - p->kcount = (u_short *)cp; - cp += kcountsize; - p->froms = (u_short *)cp; - - p->state = GMON_PROF_OFF; - p->lowpc = lowpc; - p->highpc = highpc; - p->textsize = textsize; - p->hashfraction = HASHFRACTION; - p->kcountsize = kcountsize; - p->fromssize = fromssize; - p->tolimit = tolimit; - p->tossize = tossize; - - ci->ci_gmon = p; + p->textsize, p->lowpc, p->highpc); + p->kcountsize = p->textsize / HISTFRACTION; + p->hashfraction = HASHFRACTION; + p->fromssize = p->textsize / HASHFRACTION; + p->tolimit = p->textsize * ARCDENSITY / 100; + if (p->tolimit < MINARCS) + p->tolimit = MINARCS; + else if (p->tolimit > MAXARCS) + p->tolimit = MAXARCS; + p->tossize = p->tolimit * sizeof(struct tostruct); + size = p->kcountsize + p->fromssize + p->tossize; + cp = (char *)uvm_km_zalloc(kernel_map, round_page(size)); + if (cp == 0) { + printf("No memory for profiling.\n"); + return; } + p->tos = (struct tostruct *)cp; + cp += p->tossize; + p->kcount = (u_short *)cp; + cp += p->kcountsize; + p->froms = (u_short *)cp; } /* @@ -127,32 +101,14 @@ int sysctl_doprof(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - CPU_INFO_ITERATOR cii; - struct cpu_info *ci; - struct gmonparam *gp = NULL; - int error, cpuid, op; + struct gmonparam *gp = &_gmonparam; + int error; - /* all sysctl names at this level are name and field */ - if (namelen != 2) + /* all sysctl names at this level are terminal */ + if (namelen != 1) return (ENOTDIR); /* overloaded */ - op = name[0]; - cpuid = name[1]; - - CPU_INFO_FOREACH(cii, ci) { - if (cpuid == CPU_INFO_UNIT(ci)) { - gp = ci->ci_gmon; - break; - } - } - - if (gp == NULL) - return (EOPNOTSUPP); - - /* Assume that if we're here it is safe to execute profiling. */ - gmoninit = 1; - - switch (op) { + switch (name[0]) { case GPROF_STATE: error = sysctl_int(oldp, oldlenp, newp, newlen, &gp->state); if (error) |