h1. {anchor:CHP-SDT} {{sdt}} Provider
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 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 34, Statically Defined Tracing for User Applications|Statically Defined Tracing for User Applications].
[Top|#top]
h2. {anchor:CHP-SDT-1} Probes
The SDT probes defined by the Solaris kernel are listed in [Table 22–1|#TBL-SDT]. 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 [Stability|#CHP-SDT-STABILITY].
h6. {anchor:TBL-SDT} SDT Probes
||Probe name||Description||{{arg0}}||
|{{callout-start}}|Probe that fires immediately before executing a callout (see {{<sys/callo.h>}}). Callouts are executed by periodic system clock, and represent the implementation for [{{timeout}}(9F)|http://docs.sun.com/doc/819-2256/timeout-9f?a=view].|Pointer to the {{callout_t}} (see {{<sys/callo.h>}}) corresponding to the callout to be executed.|
|{{callout-end}}|Probe that fires immediately after executing a callout (see {{<sys/callo.h>}}).|Pointer to the {{callout_t}} (see {{<sys/callo.h>}}) corresponding to the callout just executed.|
|{{interrupt-start}}|Probe that fires immediately before calling into a device's interrupt handler.|Pointer to the {{dev_info}} structure (see {{<sys/ddi_impldefs.h>}}) corresponding to the interrupting device.|
|{{interrupt-complete}}|Probe that fires immediately after returning from a device's interrupt handler.|Pointer to {{dev_info}} structure (see {{<sys/ddi_impldefs.h>}}) corresponding to the interrupting device.|
[Top|#top]
h2. {anchor:CHP-SDT-2} Examples
The following example is a script to observe callout behavior on a per-second basis:
{noformat}
#pragma D option quiet
sdt:::callout-start
{
@callouts[((callout_t *)arg0)->c_func] = count();
}
tick-1sec
{
printa("%40a %10@d\n", @callouts);
clear(@callouts);
}
{noformat}
Running this example reveals the frequent users of [{{timeout}}(9F)|http://docs.sun.com/doc/819-2256/timeout-9f?a=view] in the system, as shown in the following output:
{noformat}
# dtrace -s ./callout.d
FUNC COUNT
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
FUNC COUNT
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
FUNC COUNT
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
{noformat}
The [{{timeout}}(9F)|http://docs.sun.com/doc/819-2256/timeout-9f?a=view] 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:
{noformat}
#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);
}
{noformat}
Running this script and waiting several seconds before typing Control-C results in output similar to the following example:
{noformat}
# 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
{noformat}
The output shows that {{uhci_handle_root_hub_status_change}} in the [{{uhci}}(7D)|http://docs.sun.com/doc/819-2254/uhci-7d?a=view] 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:
{noformat}
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);
}
{noformat}
Running this script results in output similar to the following example:
{noformat}
# 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
{noformat}
[Top|#top]
h2. {anchor:CHP-SDT-3} Creating SDT Probes
If you are a device driver developer, you might be interested in creating your own SDT probes in your 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.
[Top|#top]
h3. {anchor:CHP-SDT-4} Declaring Probes
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_PROBE}}_n_ 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.
[Top|#top]
h3. {anchor:CHP-SDT-5} Probe Arguments
The arguments for each SDT probe are the arguments specified in the corresponding {{DTRACE_PROBE}}_n_ 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.
[Top|#top]
h2. {anchor:CHP-SDT-STABILITY} Stability
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 39, Stability|Stability].
||Element||Name stability||Data stability||Dependency class||
|Provider|Evolving|Evolving|ISA|
|Module|Private|Private|Unknown|
|Function|Private|Private|Unknown|
|Name|Private|Private|ISA|
|Arguments|Private|Private|ISA|
{excerpt:hidden=true}Converted by tech dogg's sgml2wiki on Tue 20 Nov 2007 at 9:27:30 PM{excerpt}
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 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 34, Statically Defined Tracing for User Applications|Statically Defined Tracing for User Applications].
[Top|#top]
h2. {anchor:CHP-SDT-1} Probes
The SDT probes defined by the Solaris kernel are listed in [Table 22–1|#TBL-SDT]. 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 [Stability|#CHP-SDT-STABILITY].
h6. {anchor:TBL-SDT} SDT Probes
||Probe name||Description||{{arg0}}||
|{{callout-start}}|Probe that fires immediately before executing a callout (see {{<sys/callo.h>}}). Callouts are executed by periodic system clock, and represent the implementation for [{{timeout}}(9F)|http://docs.sun.com/doc/819-2256/timeout-9f?a=view].|Pointer to the {{callout_t}} (see {{<sys/callo.h>}}) corresponding to the callout to be executed.|
|{{callout-end}}|Probe that fires immediately after executing a callout (see {{<sys/callo.h>}}).|Pointer to the {{callout_t}} (see {{<sys/callo.h>}}) corresponding to the callout just executed.|
|{{interrupt-start}}|Probe that fires immediately before calling into a device's interrupt handler.|Pointer to the {{dev_info}} structure (see {{<sys/ddi_impldefs.h>}}) corresponding to the interrupting device.|
|{{interrupt-complete}}|Probe that fires immediately after returning from a device's interrupt handler.|Pointer to {{dev_info}} structure (see {{<sys/ddi_impldefs.h>}}) corresponding to the interrupting device.|
[Top|#top]
h2. {anchor:CHP-SDT-2} Examples
The following example is a script to observe callout behavior on a per-second basis:
{noformat}
#pragma D option quiet
sdt:::callout-start
{
@callouts[((callout_t *)arg0)->c_func] = count();
}
tick-1sec
{
printa("%40a %10@d\n", @callouts);
clear(@callouts);
}
{noformat}
Running this example reveals the frequent users of [{{timeout}}(9F)|http://docs.sun.com/doc/819-2256/timeout-9f?a=view] in the system, as shown in the following output:
{noformat}
# dtrace -s ./callout.d
FUNC COUNT
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
FUNC COUNT
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
FUNC COUNT
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
{noformat}
The [{{timeout}}(9F)|http://docs.sun.com/doc/819-2256/timeout-9f?a=view] 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:
{noformat}
#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);
}
{noformat}
Running this script and waiting several seconds before typing Control-C results in output similar to the following example:
{noformat}
# 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
{noformat}
The output shows that {{uhci_handle_root_hub_status_change}} in the [{{uhci}}(7D)|http://docs.sun.com/doc/819-2254/uhci-7d?a=view] 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:
{noformat}
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);
}
{noformat}
Running this script results in output similar to the following example:
{noformat}
# 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
{noformat}
[Top|#top]
h2. {anchor:CHP-SDT-3} Creating SDT Probes
If you are a device driver developer, you might be interested in creating your own SDT probes in your 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.
[Top|#top]
h3. {anchor:CHP-SDT-4} Declaring Probes
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_PROBE}}_n_ 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.
[Top|#top]
h3. {anchor:CHP-SDT-5} Probe Arguments
The arguments for each SDT probe are the arguments specified in the corresponding {{DTRACE_PROBE}}_n_ 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.
[Top|#top]
h2. {anchor:CHP-SDT-STABILITY} Stability
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 39, Stability|Stability].
||Element||Name stability||Data stability||Dependency class||
|Provider|Evolving|Evolving|ISA|
|Module|Private|Private|Unknown|
|Function|Private|Private|Unknown|
|Name|Private|Private|ISA|
|Arguments|Private|Private|ISA|
{excerpt:hidden=true}Converted by tech dogg's sgml2wiki on Tue 20 Nov 2007 at 9:27:30 PM{excerpt}