summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2013-02-12 08:06:23 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2013-02-12 08:06:23 +0000
commitaa4bc9246a0fcaf361cb75d59ca7d19d72962d05 (patch)
treefc106555772640bd51b2f44ca8966b605ebe3547 /sys/kern
parent7af426a5b2c56a8f45fc6a4fa8adffb2eab344b4 (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.c6
-rw-r--r--sys/kern/subr_prof.c108
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)