Part I Designing Device Drivers for the Solaris Platform
1. Overview of Solaris Device Drivers
2. Solaris Kernel and Device Tree
5. Managing Events and Queueing Tasks
7. Device Access: Programmed I/O
10. Mapping Device and Kernel Memory
14. Layered Driver Interface (LDI)
Part II Designing Specific Kinds of Device Drivers
15. Drivers for Character Devices
18. SCSI Host Bus Adapter Drivers
19. Drivers for Network Devices
Part III Building a Device Driver
21. Compiling, Loading, Packaging, and Testing Drivers
22. Debugging, Testing, and Tuning Device Drivers
Enable the Deadman Feature to Avoid a Hard Hang
Testing With a Serial Connection
To Set Up the Host System for a tip Connection
Setting Up a Target System on the SPARC Platform
Setting Up a Target System on the x86 Platform
Loading and Unloading Test Modules
Setting kmem_flags Debugging Flags
Avoiding Data Loss on a Test System
To Boot With an Alternate Kernel
Consider Alternative Back-Up Plans
Recovering the Device Directory
Using the kmdb Kernel Debugger
Booting kmdb With an Alternate Kernel on the SPARC Platform
Booting kmdb With an Alternate Kernel on the x86 Platform
kmdb Macros for Driver Developers
Using the mdb Modular Debugger
Getting Started With the Modular Debugger
Useful Debugging Tasks With kmdb and mdb
Exploring System Registers With kmdb
Writing Debugger Commands With mdb
Obtaining Kernel Data Structure Information
Obtaining Device Tree Information
Retrieving Driver Soft State Information
23. Recommended Coding Practices
B. Summary of Solaris DDI/DKI Services
C. Making a Device Driver 64-Bit Ready
The Solaris OS provides kernel statistics structures so that you can implement counters for your driver. The DTrace facility enables you to analyze performance in real time. This section presents the following topics on device performance:
Kernel Statistics – The Solaris OS provides a set of data structures and functions for capturing performance statistics in the kernel. Kernel statistics (called kstats) enable your driver to export continuous statistics while the system is running. The kstat data is handled programmatically by using the kstat functions.
DTrace for Dynamic Instrumentation – DTrace enables you to add instrumentation to your driver dynamically so that you can perform tasks like analyzing the system and measuring performance. DTrace takes advantage of predefined kstat structures.
To assist in performance tuning, the Solaris kernel provides the kstat(3KSTAT) facility. The kstat facility provides a set of functions and data structures for device drivers and other kernel modules to export module-specific kernel statistics.
A kstat is a data structure for recording quantifiable aspects of a device's usage. A kstat is stored as a null-terminated linked list. Each kstat has a common header section and a type-specific data section. The header section is defined by the kstat_t structure.
The article “Using kstat From Within a Program in the Solaris OS” on the Sun Developer Network at http://developers.sun.com/solaris/articles/kstat_api.html provides two practical examples on how to use the kstat(3KSTAT) and libkstat(3LIB) APIs to extract metrics from the Solaris OS. The examples include “Walking Through All the kstat” and “Getting NIC kstat Output Using the Java Platform.”
The members of a kstat structure are:
Categorizes the kstat type as bus, controller, device_error, disk, hat, kmem_cache, kstat, misc, net, nfs, pages, partition, rps, ufs, vm, or vmem.
Time at which the kstat was created. ks_crtime is commonly used in calculating rates of various counters.
Points to the data section for the kstat.
Total size of the data section in bytes.
The instance of the kernel module that created this kstat. ks_instance is combined with ks_module and ks_name to give the kstat a unique, meaningful name.
Unique ID for the kstat.
Identifies the kernel module that created this kstat. ks_module is combined with ks_instance and ks_name to give the kstat a unique, meaningful name. KSTAT_STRLEN sets the maximum length of ks_module.
A name assigned to the kstat in combination with ks_module and ks_instance. KSTAT_STRLEN sets the maximum length of ks_module.
Indicates the number of data records for those kstat types that support multiple records: KSTAT_TYPE_RAW, KSTAT_TYPE_NAMED, and KSTAT_TYPE_TIMER
Points to next kstat in the chain.
A reserved field.
The timestamp for the last data snapshot, useful in calculating rates.
The data type, which can be KSTAT_TYPE_RAW for binary data, KSTAT_TYPE_NAMED for name/value pairs, KSTAT_TYPE_INTR for interrupt statistics, KSTAT_TYPE_IO for I/O statistics, and KSTAT_TYPE_TIMER for event timers.
The structures for the different kinds of kstats are:
Each kernel statistic (kstat) that is exported by device drivers consists of a header section and a data section. The kstat(9S) structure is the header portion of the statistic.
Structure for interrupt kstats. The types of interrupts are:
Hard interrupt – Sourced from the hardware device itself
Soft interrupt – Induced by the system through the use of some system interrupt source
Watchdog interrupt – Induced by a periodic timer call
Spurious interrupt – An interrupt entry point was entered but there was no interrupt to service
Multiple service – An interrupt was detected and serviced just prior to returning from any of the other types
Drivers generally report only claimed hard interrupts and soft interrupts from their handlers, but measurement of the spurious class of interrupts is useful for auto-vectored devices to locate any interrupt latency problems in a particular system configuration. Devices that have more than one interrupt of the same type should use multiple structures.
Structure for I/O kstats.
Structure for named kstats. A named kstat is an array of name-value pairs. These pairs are kept in the kstat_named structure.
The functions for using kstats are:
Allocate and initialize a kstat(9S) structure.
Remove a kstat from the system.
Add a fully initialized kstat to the system.
Initialize a named kstat. kstat_named_setstr() associates str, a string, with the named kstat pointer.
A large number of I/O subsystems have at least two basic queues of transactions to be managed. One queue is for transactions that have been accepted for processing but for which processing has yet to begin. The other queue is for transactions that are actively being processed but not yet done. For this reason, two cumulative time statistics are kept: wait time and run time. Wait time is prior to service. Run time is during the service. The kstat_queue() family of functions manages these times based on the transitions between the driver wait queue and run queue:
The kstat interface described in the following table is an effective way to obtain Ethernet physical layer statistics from the driver. Ethernet drivers should export these statistics to guide users in better diagnosis and repair of Ethernet physical layer problems. With exception of link_up, all statistics have a default value of 0 when not present. The value of the link_up statistic should be assumed to be 1.
The following example gives all the shared link setup. In this case mii is used to filter statistics.
kstat ce:0:mii:link_*
Table 22-2 Ethernet MII/GMII Physical Layer Interface Kernel Statistics
|
DTrace is a comprehensive dynamic tracing facility for examining the behavior of both user programs and the operating system itself. With DTrace, you can collect data at strategic locations in your environment, referred to as probes. DTrace enables you to record such data as stack traces, timestamps, the arguments to a function, or simply counts of how often the probe fires. Because DTrace enables you to insert probes dynamically, you do not need to recompile your code. For more information on DTrace, see the Solaris Dynamic Tracing Guide and the DTrace User Guide . The DTrace BigAdmin System Administration Portal contains many links to articles, XPerts sessions, and other information about DTrace.