The lockstat provider provides probes that can be used to discern lock contention statistics, or to understand virtually any aspect of locking behavior. The lockstat command is actually a DTrace consumer that uses the lockstat provider to gather its raw data. For more information, see lockstat(1M) man page.
The lockstat provider provides two kinds of probes: contention-event probes and hold-event probes.
Contention-event probes correspond to contention on a synchronization primitive. These probes fire when a thread is forced to wait for a resource to become available. Oracle Solaris is generally optimized for the non-contention case, so prolonged contention is not expected. You must use these probes to understand cases of contention. Because contention is relatively rare, enabling contention-event probes does not substantially affect performance.
Hold-event probes correspond to acquiring, releasing, or otherwise manipulating a synchronization primitive. You can use these probes to answer arbitrary questions about the way synchronization primitives are manipulated. Because Oracle Solaris acquires and releases synchronization primitives very often (on the order of millions of times per second per CPU on a busy system), hold-event probes has a much higher probe effect than contention-event probes. While the probe effect induced by enabling them can be substantial, it is not pathological; they may still be enabled with confidence on production systems.
The lockstat provider provides probes that correspond to the different synchronization primitives in Oracle Solaris.
Adaptive locks enforce mutual exclusion to a critical section, and may be acquired in most contexts in the kernel. Because adaptive locks have few context restrictions, they comprise the vast majority of synchronization primitives in the Oracle Solaris kernel. These locks are adaptive in their behavior with respect to contention: when a thread attempts to acquire a held adaptive lock, it will determine if the owning thread is currently running on a CPU. If the owner is running on another CPU, the acquiring thread will spin. If the owner is not running, the acquiring thread will block.
The following table lists the lockstat probes pertaining to adaptive locks. For each probe, arg0 contains a pointer to the kmutex_t structure that represents the adaptive lock.
|
Threads cannot block in some contexts in the kernel, such as high-level interrupt context and any context manipulating dispatcher state. In these contexts, this restriction prevents the use of adaptive locks. Spin locks are instead used to effect mutual exclusion to critical sections in these contexts. As the name implies, the behavior of these locks in the presence of contention is to spin until the lock is released by the owning thread. The following table describes the probes related to spin locks.
|
Adaptive locks are much more common than spin locks. The following script displays the total for both lock types to provide data to support this observation.
lockstat:::adaptive-acquire /execname == "date"/ { @locks["adaptive"] = count(); } lockstat:::spin-acquire /execname == "date"/ { @locks["spin"] = count(); }
Run this script in one window, and the date command in another window. When you terminate the DTrace script, you will see output similar to the following example:
# dtrace -s ./whatlock.d dtrace: script './whatlock.d' matched 5 probes ^C spin 26 adaptive 2981
As this output indicates, over 99 percent of the locks acquired in running the date command are adaptive locks. It may be surprising that so many locks are acquired in doing something as simple as a date. The large number of locks is a natural artifact of the fine-grained locking required of an extremely scalable system like the Oracle Solaris kernel.
Thread locks are a special kind of spin lock that are used to lock a thread for purposes of changing thread state. Thread lock hold events are available as spin lock hold-event probes (that is, spin-acquire and spin-release), but contention events have their own probe specific to thread locks.
thread-spin is the contention-event probe that fires after a thread has spun on a thread lock. Like other contention-event probes, if both the contention-event probe and the hold-event probe are enabled, thread-spin will fire before spin-acquire. Unlike other contention-event probes, however, thread-spin fires before the lock is actually acquired. As a result, multiple thread-spin probe firings may correspond to a single spin-acquire probe firing.
Readers/writer locks enforce a policy of allowing multiple readers or a single writer, but not both to be in a critical section. These locks are typically used for structures that are searched more frequently than they are modified and for which there is substantial time in the critical section. If critical section times are short, readers/writer locks will implicitly serialize over the shared memory used to implement the lock, giving them no advantage over adaptive locks. See rwlock(9F) for more details on readers/writer locks.
The probes pertaining to readers/writer locks are in Figure 31, Table 31, List of lockstat Readers/Writer Lock Probes. For each probe, arg0 contains a pointer to the krwlock_t structure that represents the adaptive lock.
|
The lockstat provider uses DTrace's stability mechanism to describe its stabilities as shown in the following table. For more information about the stability mechanism, see DTrace Stability Mechanisms.
|