diff options
author | 2013-03-12 09:37:16 +0000 | |
---|---|---|
committer | 2013-03-12 09:37:16 +0000 | |
commit | 6377c2eaf8ad0c2174b64c6ffe780441bba1d2d3 (patch) | |
tree | a11ced68cffe11872ad507f4059aa237d0dd3097 /sys/lib/libkern/mcount.c | |
parent | Add support for the -L and -P options. (diff) | |
download | wireguard-openbsd-6377c2eaf8ad0c2174b64c6ffe780441bba1d2d3.tar.xz wireguard-openbsd-6377c2eaf8ad0c2174b64c6ffe780441bba1d2d3.zip |
Fix kernel profiling on MP systems by using per-CPU buffers and teach
kgmon(8) to deal with them, this time without public header changes.
Previously various CPUs were iterating over the same global buffer at
the same time to modify it and never ended.
This diff includes some ideas submited by Thor Simon to NetBSD via miod@.
ok deraadt@, mikeb@, haesbaert@
Diffstat (limited to 'sys/lib/libkern/mcount.c')
-rw-r--r-- | sys/lib/libkern/mcount.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sys/lib/libkern/mcount.c b/sys/lib/libkern/mcount.c index c66314cefe0..684ddadb9aa 100644 --- a/sys/lib/libkern/mcount.c +++ b/sys/lib/libkern/mcount.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mcount.c,v 1.12 2013/02/12 08:06:22 mpi Exp $ */ +/* $OpenBSD: mcount.c,v 1.13 2013/03/12 09:37:16 mpi Exp $ */ /* $NetBSD: mcount.c,v 1.3.6.1 1996/06/12 04:23:01 cgd Exp $ */ /*- @@ -43,13 +43,10 @@ * _mcount updates data structures that represent traversals of the * program's call graph edges. frompc and selfpc are the return * address and function address that represents the given call graph edge. - * - * Note: the original BSD code used the same variable (frompcindex) for - * both frompcindex and frompc. Any reasonable, modern compiler will - * perform this optimization. */ _MCOUNT_DECL(u_long frompc, u_long selfpc) __used; -_MCOUNT_DECL(u_long frompc, u_long selfpc) /* _mcount; may be static, inline, etc */ +/* _mcount; may be static, inline, etc */ +_MCOUNT_DECL(u_long frompc, u_long selfpc) { u_short *frompcindex; struct tostruct *top, *prevtop; @@ -57,9 +54,21 @@ _MCOUNT_DECL(u_long frompc, u_long selfpc) /* _mcount; may be static, inline, et long toindex; #ifdef _KERNEL int s; -#endif + /* + * Do not profile execution if memory for the current CPU + * desciptor and profiling buffers has not yet been allocated + * or if the CPU we are running on has not yet set its trap + * handler. + */ + if (gmoninit == 0) + return; + + if ((p = curcpu()->ci_gmon) == NULL) + return; +#else p = &_gmonparam; +#endif /* * check that we are profiling * and that we aren't recursively invoked. @@ -156,7 +165,6 @@ _MCOUNT_DECL(u_long frompc, u_long selfpc) /* _mcount; may be static, inline, et *frompcindex = toindex; goto done; } - } done: #ifdef _KERNEL |