(update of http://marc.theaimsgroup.com/?l=openbsd-misc&m=115898040215357&w=2)

Here's an improved version of the patch.  It does away with
kmstartup(), completing the coverage of the recorded call graph.

--- /dev/null   Sun Sep 24 23:24:37 2006
+++ sys/conf/gen_addr_etext     Sat Sep 23 00:36:45 2006
@@ -0,0 +1,19 @@
+#!/bin/sh
+f=addr_etext.h
+l='#define ADDR_ETEXT 0x\'
+if [ $# = 0 ]; then
+       echo "$l" > $f
+       echo '0 + KERNBASE + (1<<16)' >> $f
+       exit 0
+fi
+if [ $# = 1 ]; then
+       a=$(objdump -t "$1" | awk '/ etext$/{print $1}')
+       [ -z "$a" ] && exit 2
+       b=$(sed -n 2p < $f)
+       [ -z "$b" ] && exit 2
+       [ x"$a" = x"$b" ] && exit 1
+       echo "$l" > $f
+       echo "$a" >> $f
+       exit 0
+fi
+exit 2
Index: sys/kern/init_main.c
===================================================================
RCS file: /cvs/src/sys/kern/init_main.c,v
retrieving revision 1.130
diff -u -r1.130 init_main.c
--- sys/kern/init_main.c        6 May 2006 23:02:36 -0000       1.130
+++ sys/kern/init_main.c        24 Sep 2006 23:24:42 -0000
@@ -347,6 +347,9 @@
 
        /* Start real time and statistics clocks. */
        initclocks();
+#ifdef GPROF
+       startprofclock(&proc0);
+#endif
 
        /* Lock the kernel on behalf of proc0. */
        KERNEL_PROC_LOCK(p);
@@ -385,11 +388,6 @@
        domaininit();
        if_attachdomain();
        splx(s);
-
-#ifdef GPROF
-       /* Initialize kernel profiling. */
-       kmstartup();
-#endif
 
 #if !defined(NO_PROPOLICE)
        {
Index: sys/kern/subr_prof.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_prof.c,v
retrieving revision 1.15
diff -u -r1.15 subr_prof.c
--- sys/kern/subr_prof.c        9 Dec 2005 09:09:52 -0000       1.15
+++ sys/kern/subr_prof.c        24 Sep 2006 23:24:42 -0000
@@ -45,53 +45,40 @@
 #ifdef GPROF
 #include <sys/malloc.h>
 #include <sys/gmon.h>
-#include <uvm/uvm_extern.h>
+#include "addr_etext.h"
 
 /*
- * Froms is actually a bunch of unsigned shorts indexing tos
+ * 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.
  */
-struct gmonparam _gmonparam = { GMON_PROF_OFF };
-
-extern char etext[];
-
+#define LOWPC ROUNDDOWN(KERNBASE, HISTFRACTION * sizeof(HISTCOUNTER))
+#define HIGHPC ROUNDUP((ADDR_ETEXT), HISTFRACTION * sizeof(HISTCOUNTER))
+#define TEXTSIZE (HIGHPC - LOWPC)
+#define KCOUNTSIZE (TEXTSIZE / HISTFRACTION)
+#define FROMSSIZE (TEXTSIZE / HASHFRACTION)
+#define TOLIM (TEXTSIZE * ARCDENSITY / 100)
+#define TOLIMIT (TOLIM < MINARCS ? MINARCS : TOLIM > MAXARCS ? MAXARCS : TOLIM)
+#define TOSSIZE (TOLIMIT * sizeof(struct tostruct))
 
-void
-kmstartup(void)
-{
-       char *cp;
-       struct gmonparam *p = &_gmonparam;
-       int size;
+static char buf[KCOUNTSIZE + FROMSSIZE + TOSSIZE];
 
-       /*
-        * 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.
-        */
-       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",
-              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;
-}
+/*
+ * Froms is actually a bunch of unsigned shorts indexing tos
+ */
+struct gmonparam _gmonparam = {
+       /* state = */ GMON_PROF_ON,
+       /* kcount = */ (ushort *)(buf + TOSSIZE),
+       KCOUNTSIZE,
+       /* froms = */ (ushort *)(buf + TOSSIZE + KCOUNTSIZE),
+       FROMSSIZE,
+       /* tos = */ (struct tostruct *)buf,
+       TOSSIZE,
+       TOLIMIT,
+       LOWPC,
+       HIGHPC,
+       TEXTSIZE,
+       HASHFRACTION
+};
 
 /*
  * Return kernel profiling information.
Index: usr.sbin/config/mkmakefile.c
===================================================================
RCS file: /cvs/src/usr.sbin/config/mkmakefile.c,v
retrieving revision 1.20
diff -u -r1.20 mkmakefile.c
--- usr.sbin/config/mkmakefile.c        6 May 2006 11:31:46 -0000       1.20
+++ usr.sbin/config/mkmakefile.c        24 Sep 2006 23:24:42 -0000
@@ -42,6 +42,7 @@
  */
 
 #include <sys/param.h>
+#include <sys/wait.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdio.h>
@@ -167,6 +168,8 @@
 #endif
 }
 
+static int option_gprof = 0;
+
 static int
 emitdefs(FILE *fp)
 {
@@ -177,6 +180,8 @@
                return (1);
        sp = "";
        for (nv = options; nv != NULL; nv = nv->nv_next) {
+               if (!strcmp(nv->nv_name, "GPROF"))
+                       option_gprof = 1;
                if (ht_lookup(defopttab, nv->nv_name) != NULL)
                        continue;
                if (fprintf(fp, "%s-D%s", sp, nv->nv_name) < 0)
@@ -186,6 +191,18 @@
                        return 1;
                sp = " ";
        }
+       if (option_gprof) {
+               size_t len = strlen(srcdir) + 30;
+               char *buf = emalloc(len);
+               int s;
+
+               if (strchr(srcdir, '\''))
+                       panic("'ouch");
+               snprintf(buf, len, "sh -- '%s/conf/gen_addr_etext'", srcdir);
+               s = system(buf);
+               if (s == -1 || !WIFEXITED(s) || WEXITSTATUS(s))
+                       panic("gen_addr_etext");
+       }
        if (putc('\n', fp) < 0)
                return (1);
        if (fprintf(fp, "PARAM=-DMAXUSERS=%d\n", maxusers) < 0)
@@ -444,9 +461,15 @@
                if (fprintf(fp, "\n"
                    "\t${SYSTEM_LD_HEAD}\n"
                    "\t${SYSTEM_LD} swap%s.o\n"
-                   "\t${SYSTEM_LD_TAIL}\n"
+                   "\t${SYSTEM_LD_TAIL}\n", swname) < 0)
+                       return (1);
+               if (option_gprof && fputs(
+                   "\tif sh $S/conf/gen_addr_etext $@; then make $@;"
+                   " else [ $$? = 1 ]; fi\n", fp) < 0)
+                       return (1);
+               if (fprintf(fp,
                    "\n"
-                   "swap%s.o: ", swname, swname) < 0)
+                   "swap%s.o: ", swname) < 0)
                        return (1);
                if (cf->cf_root != NULL) {
                        if (fprintf(fp, "swap%s.c\n", nm) < 0)

Reply via email to