Skip Navigation Links | |
Exit Print View | |
Oracle Solaris 11.1 Dynamic Tracing Guide Oracle Solaris 11.1 Information Library |
Co-existence With Existing Tools
cpucaps-sleep and cpucaps-wakeup
args[4] - ipv4info_t Structure
args[5] - ipv6info_t Structure
Remote Port Login/Logout Event Probes
13. Statically Defined Tracing for User Applications
The Statically Defined Tracing (SDT) provider creates probes at sites that a software programmer has formally designated. The SDT mechanism allows programmers to consciously choose locations of interest to users of DTrace and to convey some semantic knowledge about each location through the probe name. The Oracle Solaris kernel has defined a handful of SDT probes, and will likely add more over time. DTrace also provides a mechanism for user application developers to define static probes, described in Chapter 13, Statically Defined Tracing for User Applications.
The SDT probes defined by the Oracle Solaris kernel are listed in the following table. The name stability and data stability of these probes are both Private because their description here thus reflects the kernel's implementation and should not be inferred to be an interface commitment. For more information about the DTrace stability mechanism, see Chapter 18, Stability.
Table 11-9 SDT Probes
|
The following example is a script to observe callout behavior on a per-second basis:
#pragma D option quiet sdt:::callout-start { @callouts[((callout_t *)arg0)->c_func] = count(); } tick-1sec { printa("%40a %10@d\n", @callouts); clear(@callouts); }
Running this example reveals the frequent users of timeout(9F) in the system, as shown in the following output:
# dtrace -s ./callout.d TS`ts_update 1 uhci`uhci_cmd_timeout_hdlr 3 genunix`setrun 5 genunix`schedpaging 5 ata`ghd_timeout 10 uhci`uhci_handle_root_hub_status_change 309 ip`tcp_time_wait_collector 1 TS`ts_update 1 uhci`uhci_cmd_timeout_hdlr 3 genunix`schedpaging 4 genunix`setrun 8 ata`ghd_timeout 10 uhci`uhci_handle_root_hub_status_change 300 ip`tcp_time_wait_collector 0 iprb`mii_portmon 1 TS`ts_update 1 uhci`uhci_cmd_timeout_hdlr 3 genunix`schedpaging 4 genunix`setrun 7 ata`ghd_timeout 10 uhci`uhci_handle_root_hub_status_change 300
The timeout(9F) interface only produces a single timer expiration. Consumers of timeout requiring interval timer functionality typically reinstall their timeout from their timeout handler. The following example shows this behavior:
#pragma D option quiet sdt:::callout-start { self->callout = ((callout_t *)arg0)->c_func; } fbt::timeout:entry /self->callout && arg2 <= 100/ { /* * In this case, we are most interested in interval timeout(9F)s that * are short. We therefore do a linear quantization from 0 ticks to * 100 ticks. The system clock's frequency - set by the variable * "hz" - defaults to 100, so 100 system clock ticks is one second. */ @callout[self->callout] = lquantize(arg2, 0, 100); } sdt:::callout-end { self->callout = NULL; } END { printa("%a\n%@d\n\n", @callout); }
Running this script and waiting several seconds before typing Control-C results in output similar to the following example:
# dtrace -s ./interval.d ^C genunix`schedpaging value ------------- Distribution ------------- count 24 | 0 25 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 20 26 | 0 ata`ghd_timeout value ------------- Distribution ------------- count 9 | 0 10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 51 11 | 0 uhci`uhci_handle_root_hub_status_change value ------------- Distribution ------------- count 0 | 0 1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1515 2 | 0
The output shows that uhci_handle_root_hub_status_change in the uhci(7D) driver represents the shortest interval timer on the system: it is called every system clock tick.
The interrupt-start probe can be used to understand interrupt activity. The following example shows how to quantize the time spent executing an interrupt handler by driver name:
interrupt-start { self->ts = vtimestamp; } interrupt-complete /self->ts/ { this->devi = (struct dev_info *)arg0; @[stringof(`devnamesp[this->devi->devi_major].dn_name), this->devi->devi_instance] = quantize(vtimestamp - self->ts); }
Running this script results in output similar to the following example:
# dtrace -s ./intr.d dtrace: script './intr.d' matched 2 probes ^C isp 0 value ------------- Distribution ------------- count 8192 | 0 16384 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1 32768 | 0 pcf8584 0 value ------------- Distribution ------------- count 64 | 0 128 | 2 256 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 157 512 |@@@@@@ 31 1024 | 3 2048 | 0 pcf8584 1 value ------------- Distribution ------------- count 2048 | 0 4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 154 8192 |@@@@@@@ 37 16384 | 2 32768 | 0 qlc 0 value ------------- Distribution ------------- count 16384 | 0 32768 |@@ 9 65536 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 126 131072 |@ 5 262144 | 2 524288 | 0 hme 0 value ------------- Distribution ------------- count 1024 | 0 2048 | 6 4096 | 2 8192 |@@@@ 89 16384 |@@@@@@@@@@@@@ 262 32768 |@ 37 65536 |@@@@@@@ 139 131072 |@@@@@@@@ 161 262144 |@@@ 73 524288 | 4 1048576 | 0 2097152 | 1 4194304 | 0 ohci 0 value ------------- Distribution ------------- count 8192 | 0 16384 | 3 32768 | 1 65536 |@@@ 143 131072 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1368 262144 | 0
If you are a device driver developer, you might be interested in creating your own SDT probes in your Oracle Solaris driver. The disabled probe effect of SDT is essentially the cost of several no-operation machine instructions. You are therefore encouraged to add SDT probes to your device drivers as needed. Unless these probes negatively affect performance, you can leave them in your shipping code.
SDT probes are declared using the DTRACE_PROBE, DTRACE_PROBE1, DTRACE_PROBE2, DTRACE_PROBE3 and DTRACE_PROBE4 macros from <sys/sdt.h>. The module name and function name of an SDT-based probe corresponds to the kernel module and function of the probe. The name of the probe depends on the name given in the DTRACE_PROBEn macro. If the name contains no two consecutive underbars (_), the name of the probe is as written in the macro. If the name contains any two consecutive underbars, the probe name converts the consecutive underbars to a single dash (-). For example, if a DTRACE_PROBE macro specifies transaction_start, the SDT probe will be named transaction-start. This substitution allows C code to provide macro names that are not valid C identifiers without specifying a string.
DTrace includes the kernel module name and function name as part of the tuple identifying a probe, so you do not need to include this information in the probe name to prevent name space collisions. You can use the command dtrace -l -P sdt -m module on your driver module to list the probes you have installed and the full names that will be seen by users of DTrace.
The arguments for each SDT probe are the arguments specified in the corresponding DTRACE_PROBEn macro reference. The number of arguments depends on which macro was used to create the probe: DTRACE_PROBE1 specifies one argument, DTRACE_PROBE2 specifies two arguments, and so on. When declaring your SDT probes, you can minimize their disabled probe effect by not dereferencing pointers and not loading from global variables in the probe arguments. Both pointer dereferencing and global variable loading may be done safely in D actions that enable probes, so DTrace users can request these actions only when they are needed.
The SDT provider uses DTrace's stability mechanism to describe its stabilities, as shown in the following table. For more information about the stability mechanism, see Chapter 18, Stability.
|