aboutsummaryrefslogtreecommitdiff
path: root/cddl
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2024-06-19 20:57:09 +0000
committerMark Johnston <markj@FreeBSD.org>2024-06-19 20:57:41 +0000
commitddf0ed09bd8f83677407db36828aca2c10f419c9 (patch)
treeeba8d6a5a0cf3b74bb8a7246997b66a0d2583bc7 /cddl
parente5a7890dc00ac0b158498db92008f7c0b5970eac (diff)
downloadsrc-ddf0ed09bd8f83677407db36828aca2c10f419c9.tar.gz
src-ddf0ed09bd8f83677407db36828aca2c10f419c9.zip
sdt: Implement SDT probes using hot-patching
The idea here is to avoid a memory access and conditional branch per probe site. Instead, the probe is represented by an "unreachable" unconditional function call. asm goto is used to store the address of the probe site (represented by a no-op sled) and the address of the function call into a tracepoint record. Each SDT probe carries a list of tracepoints. When the probe is enabled, the no-op sled corresponding to each tracepoint is overwritten with a jmp to the corresponding label. The implementation uses smp_rendezvous() to park all other CPUs while the instruction is being overwritten, as this can't be done atomically in general. The compiler moves argument marshalling code and the sdt_probe() function call out-of-line, i.e., to the end of the function. Per gallatin@ in D43504, this approach has less overhead when probes are disabled. To make the implementation a bit simpler, I removed support for probes with 7 arguments; nothing makes use of this except a regression test case. It could be re-added later if need be. The approach taken in this patch enables some more improvements: 1. We can now automatically fill out the "function" field of SDT probe names. The SDT macros let the programmer specify the function and module names, but this is really a bug and shouldn't have been allowed. The intent was to be able to have the same probe in multiple functions and to let the user restrict which probes actually get enabled by specifying a function name or glob. 2. We can avoid branching on SDT_PROBES_ENABLED() by adding the ability to include blocks of code in the out-of-line path. For example: if (SDT_PROBES_ENABLED()) { int reason = CLD_EXITED; if (WCOREDUMP(signo)) reason = CLD_DUMPED; else if (WIFSIGNALED(signo)) reason = CLD_KILLED; SDT_PROBE1(proc, , , exit, reason); } could be written SDT_PROBE1_EXT(proc, , , exit, reason, int reason; reason = CLD_EXITED; if (WCOREDUMP(signo)) reason = CLD_DUMPED; else if (WIFSIGNALED(signo)) reason = CLD_KILLED; ); In the future I would like to use this mechanism more generally, e.g., to remove branches and marshalling code used by hwpmc, and generally to make it easier to add new tracepoint consumers without having to add more conditional branches to hot code paths. Reviewed by: Domagoj Stolfa, avg MFC after: 2 months Differential Revision: https://reviews.freebsd.org/D44483
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d11
1 files changed, 5 insertions, 6 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
index e965b05f2405..d3f7bfad5db1 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
@@ -27,7 +27,7 @@
#pragma ident "%Z%%M% %I% %E% SMI"
/*
- * ASSERTION: Verify that argN (1..7) variables are properly remapped.
+ * ASSERTION: Verify that argN (1..6) variables are properly remapped.
*/
BEGIN
@@ -44,13 +44,12 @@ ERROR
}
test:::sdttest
-/arg0 != 1 || arg1 != 2 || arg2 != 3 || arg3 != 4 || arg4 != 5 || arg5 != 6 ||
- arg6 != 7/
+/arg0 != 1 || arg1 != 2 || arg2 != 3 || arg3 != 4 || arg4 != 5 || arg5 != 6/
{
printf("sdt arg mismatch\n\n");
- printf("args are : %d, %d, %d, %d, %d, %d, %d\n", arg0, arg1, arg2,
- arg3, arg4, arg5, arg6);
- printf("should be : 1, 2, 3, 4, 5, 6, 7\n");
+ printf("args are : %d, %d, %d, %d, %d, %d\n", arg0, arg1, arg2,
+ arg3, arg4, arg5);
+ printf("should be : 1, 2, 3, 4, 5, 6\n");
exit(1);
}