Add kmupetext(), a function that expands the range of memory covered
by the profiler on a running system. This is not done sparsely, as memory is cheaper than processor speed and each gprof mcount() and mexitcount() operation is already very expensive. Obtained from: NAI Labs CBOSS project Funded by: DARPA
This commit is contained in:
parent
35609d458d
commit
4a44bd4b4a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=85733
@ -117,6 +117,7 @@ typedef u_int fptrdiff_t;
|
||||
#ifdef _KERNEL
|
||||
|
||||
void mcount __P((uintfptr_t frompc, uintfptr_t selfpc));
|
||||
void kmupetext __P((uintfptr_t nhighpc));
|
||||
|
||||
#ifdef GUPROF
|
||||
struct gmonparam;
|
||||
|
@ -117,6 +117,7 @@ typedef u_int fptrdiff_t;
|
||||
#ifdef _KERNEL
|
||||
|
||||
void mcount __P((uintfptr_t frompc, uintfptr_t selfpc));
|
||||
void kmupetext __P((uintfptr_t nhighpc));
|
||||
|
||||
#ifdef GUPROF
|
||||
struct gmonparam;
|
||||
|
@ -78,6 +78,69 @@ nullfunc_profiled()
|
||||
}
|
||||
#endif /* GUPROF */
|
||||
|
||||
/*
|
||||
* Update the histograms to support extending the text region arbitrarily.
|
||||
* This is done slightly naively (no sparse regions), so will waste slight
|
||||
* amounts of memory, but will overall work nicely enough to allow profiling
|
||||
* of KLDs.
|
||||
*/
|
||||
void
|
||||
kmupetext(uintfptr_t nhighpc)
|
||||
{
|
||||
struct gmonparam np; /* slightly large */
|
||||
struct gmonparam *p = &_gmonparam;
|
||||
char *cp;
|
||||
critical_t savecrit;
|
||||
|
||||
GIANT_REQUIRED;
|
||||
bcopy(p, &np, sizeof(*p));
|
||||
np.highpc = ROUNDUP(nhighpc, HISTFRACTION * sizeof(HISTCOUNTER));
|
||||
if (np.highpc <= p->highpc)
|
||||
return;
|
||||
np.textsize = np.highpc - p->lowpc;
|
||||
np.kcountsize = np.textsize / HISTFRACTION;
|
||||
np.hashfraction = HASHFRACTION;
|
||||
np.fromssize = np.textsize / HASHFRACTION;
|
||||
np.tolimit = np.textsize * ARCDENSITY / 100;
|
||||
if (np.tolimit < MINARCS)
|
||||
np.tolimit = MINARCS;
|
||||
else if (np.tolimit > MAXARCS)
|
||||
np.tolimit = MAXARCS;
|
||||
np.tossize = np.tolimit * sizeof(struct tostruct);
|
||||
cp = malloc(np.kcountsize + np.fromssize + np.tossize,
|
||||
M_GPROF, M_WAITOK);
|
||||
/*
|
||||
* Check for something else extending highpc while we slept.
|
||||
*/
|
||||
if (np.highpc <= p->highpc) {
|
||||
free(cp, M_GPROF);
|
||||
return;
|
||||
}
|
||||
np.tos = (struct tostruct *)cp;
|
||||
cp += np.tossize;
|
||||
np.kcount = (HISTCOUNTER *)cp;
|
||||
cp += np.kcountsize;
|
||||
np.froms = (u_short *)cp;
|
||||
#ifdef GUPROF
|
||||
/* Reinitialize pointers to overhead counters. */
|
||||
np.cputime_count = &KCOUNT(&np, PC_TO_I(&np, cputime));
|
||||
np.mcount_count = &KCOUNT(&np, PC_TO_I(&np, mcount));
|
||||
np.mexitcount_count = &KCOUNT(&np, PC_TO_I(&np, mexitcount));
|
||||
#endif
|
||||
savecrit = critical_enter();
|
||||
bcopy(p->tos, np.tos, p->tossize);
|
||||
bzero((char *)np.tos + p->tossize, np.tossize - p->tossize);
|
||||
bcopy(p->kcount, np.kcount, p->kcountsize);
|
||||
bzero((char *)np.kcount + p->kcountsize, np.kcountsize -
|
||||
p->kcountsize);
|
||||
bcopy(p->froms, np.froms, p->fromssize);
|
||||
bzero((char *)np.froms + p->fromssize, np.fromssize - p->fromssize);
|
||||
cp = (char *)p->tos;
|
||||
bcopy(&np, p, sizeof(*p));
|
||||
critical_exit(savecrit);
|
||||
free(cp, M_GPROF);
|
||||
}
|
||||
|
||||
static void
|
||||
kmstartup(dummy)
|
||||
void *dummy;
|
||||
@ -115,11 +178,7 @@ kmstartup(dummy)
|
||||
p->tolimit = MAXARCS;
|
||||
p->tossize = p->tolimit * sizeof(struct tostruct);
|
||||
cp = (char *)malloc(p->kcountsize + p->fromssize + p->tossize,
|
||||
M_GPROF, M_NOWAIT | M_ZERO);
|
||||
if (cp == 0) {
|
||||
printf("No memory for profiling.\n");
|
||||
return;
|
||||
}
|
||||
M_GPROF, M_WAITOK | M_ZERO);
|
||||
p->tos = (struct tostruct *)cp;
|
||||
cp += p->tossize;
|
||||
p->kcount = (HISTCOUNTER *)cp;
|
||||
|
Loading…
Reference in New Issue
Block a user