xref: /freebsd/share/man/man9/devstat.9 (revision 6e8394b8baa7d5d9153ab90de6824bcd19b3b4e1)
1.\"
2.\" Copyright (c) 1998, 1999 Kenneth D. Merry.
3.\" All rights reserved.
4.\"
5.\" Redistribution and use in source and binary forms, with or without
6.\" modification, are permitted provided that the following conditions
7.\" are met:
8.\" 1. Redistributions of source code must retain the above copyright
9.\"    notice, this list of conditions and the following disclaimer.
10.\" 2. Redistributions in binary form must reproduce the above copyright
11.\"    notice, this list of conditions and the following disclaimer in the
12.\"    documentation and/or other materials provided with the distribution.
13.\" 3. The name of the author may not be used to endorse or promote products
14.\"    derived from this software without specific prior written permission.
15.\"
16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26.\" SUCH DAMAGE.
27.\"
28.\"	$Id: devstat.9,v 1.2 1999/02/10 00:02:53 ken Exp $
29.\"
30.Dd May 22, 1998
31.Dt DEVSTAT 9
32.Os FreeBSD 3.0
33.Sh NAME
34.Nm devstat
35.Nd kernel interface for keeping device statistics
36.Sh SYNOPSIS
37.Fd #include <sys/devicestat.h>
38.Ft void
39.Fo devstat_add_entry
40.Fa "struct devstat *ds"
41.Fa "const char *dev_name"
42.Fa "int unit_number"
43.Fa "u_int32_t block_size"
44.Fa "devstat_support_flags flags"
45.Fa "devstat_type_flags device_type"
46.Fa "devstat_priority priority"
47.Fc
48.Ft void
49.Fn devstat_remove_entry "struct devstat *ds"
50.Ft void
51.Fn devstat_start_transaction "struct devstat *ds"
52.Ft void
53.Fo devstat_end_transaction
54.Fa "struct devstat *ds"
55.Fa "u_int32_t bytes"
56.Fa "devstat_tag_type tag_type"
57.Fa "devstat_trans_flags flags"
58.Fc
59.Sh DESCRIPTION
60The devstat subsystem is an interface for recording device
61statistics, as its name implies.  The idea is to keep reasonably detailed
62statistics while utilizing a minimum amount of CPU time to record them.
63Thus, no statistical calculations are actually performed in the kernel
64portion of the
65.Nm
66code.  Instead, that is left for user programs to handle.
67.Pp
68.Fn devstat_add_entry
69registers a device with the
70.Nm
71subsystem.  The caller is expected to have already allocated \fBand zeroed\fR
72the devstat structure before calling this function.
73.Fn devstat_add_entry
74takes several arguments:
75.Bl -tag -width device_type
76.It ds
77The
78.Va devstat
79structure, allocated and zeroed by the client.
80.It dev_name
81The device name. e.g. da, cd, sa.
82.It unit_number
83Device unit number.
84.It block_size
85Block size of the device, if supported.  If the device does not support a
86block size, or if the blocksize is unknown at the time the device is added
87to the
88.Nm
89list, it should be set to 0.
90.It flags
91Flags indicating operations supported or not supported by the device.  See
92below for details.
93.It device_type
94The device type.  This is broken into three sections:  base device type
95(e.g. direct access, CDROM, sequential access), interface type (IDE, SCSI
96or other) and a passthrough flag to indicate pasthrough devices.  See below
97for a complete list of types.
98.It priority
99The device priority.  The priority is used to determine how devices are
100sorted within
101.Nm devstat's
102list of devices.  Devices are sorted first by priority (highest to lowest),
103and then by attach order.  See below for a complete list of available
104priorities.
105.El
106.Pp
107.Fn devstat_remove_entry
108removes a device from the
109.Nm
110subsystem.  It takes the devstat structure for the device in question as
111an argument.  The
112.Nm
113generation number is incremented and the number of devices is decremented.
114.Pp
115.Fn devstat_start_transaction
116registers the start of a transaction with the
117.Nm
118subsystem.  The busy count is incremented with each transaction start.
119When a device goes from idle to busy, the system uptime is recorded in the
120.Va start_time
121field of the
122.Va devstat
123structure.
124.Pp
125.Fn devstat_end_transaction
126registers the end of a transaction with the
127.Nm
128subsystem.  It takes four arguments:
129.Bl -tag -width tag_type
130.It ds
131The
132.Va devstat
133structure for the device in question.
134.It bytes
135The number of bytes transferred in this transaction.
136.It tag_type
137Transaction tag type.  See below for tag types.
138.It flags
139Transaction flags indicating whether the transaction was a read, write, or
140whether no data was transferred.
141.El
142.Pp
143The
144.Va devstat
145structure is composed of the following fields:
146.Bl -tag -width dev_creation_time
147.It dev_links
148Each
149.Va devstat
150structure is placed in a linked list when it is registered.  The
151.Va dev_links
152field contains a pointer to the next entry in the list of
153.Va devstat
154structures.
155.It device_number
156The device number is a unique identifier for each device.  The device
157number is incremented for each new device that is registered.  The device
158number is currently only a 32-bit integer, but it could be enlarged if
159someone has a system with more than four billion device arrival events.
160.It device_name
161The device name is a text string given by the registering driver to
162identify itself.  (e.g.
163.Dq da ,
164.Dq cd ,
165.Dq sa ,
166etc.)
167.It unit_number
168The unit number identifies the particular instance of the peripheral driver
169in question.
170.It bytes_written
171This is the number of bytes that have been written to the device.  This
172number is currently an unsigned 64 bit integer.  This will hopefully
173eliminate the counter wrap that would come very quickly on some systems if
17432 bit integers were used.
175.It bytes_read
176This is the number of bytes that have been read from the device.
177.It num_reads
178This is the number of reads from the device.
179.It num_writes
180This is the number of writes to the device.
181.It num_other
182This is the number of transactions to the device which are neither reads or
183writes.  For instance,
184.Tn SCSI
185drivers often send a test unit ready command to
186.Tn SCSI
187devices.  The test unit ready command does not read or write any data.  It
188merely causes the device to return its status.
189.It busy_count
190This is the current number of outstanding transactions for the device.
191This should never go below zero, and on an idle device it should be zero.
192If either one of these conditions is not true, it indicates a problem in
193the way
194.Fn devstat_start_transaction
195and
196.Fn devstat_end_transaction
197are being called in client code.  There should be one and only one
198transaction start event and one transaction end event for each transaction.
199.It block_size
200This is the block size of the device, if the device has a block size.
201.It tag_types
202This is an array of counters to record the number of various tag types that
203are sent to a device.  See below for a list of tag types.
204.It dev_creation_time
205This is the time, as reported by
206.Fn getmicrotime
207that the device was registered.
208.It busy_time
209This is the amount of time that the device busy count has been greater than
210zero.  This is only updated when the busy count returns to zero.
211.It start_time
212This is the time, as reported by
213.Fn getmicrouptime
214that the device busy count went from zero to one.
215.It last_comp_time
216This is the time as reported by
217.Fn getmicrouptime
218that a transaction last completed.  It is used along with
219.Va start_time
220to calculate the device busy time.
221.It flags
222These flags indicate which statistics measurements are supported by a
223particular device.  These flags are primarily intended to serve as an aid
224to userland programs that decipher the statistics.
225.It device_type
226This is the device type.  It consists of three parts:  the device type
227(e.g. direct access, CDROM, sequential access, etc.), the interface (IDE,
228SCSI or other) and whether or not the device in question is a passthrough
229driver.  See below for a complete list of device types.
230.It priority
231This is the priority.  This is the first parameter used to determine where
232to insert a device in the
233.Nm devstat
234list.  The second parameter is attach order.  See below for a list of
235available priorities.
236.El
237.Pp
238Each device is given a device type.  Passthrough devices have the same
239underlying device type and interface as the device they provide an
240interface for, but they also have the passthrough flag set.  The base
241device types are identical to the
242.Tn SCSI
243device type numbers, so with
244.Tn SCSI
245peripherals, the device type returned from an inquiry is usually ORed with
246the
247.Tn SCSI
248interface type and the passthrough flag if appropriate.  The device type
249flags are as follows:
250.Bd -literal -offset indent
251typedef enum {
252	DEVSTAT_TYPE_DIRECT	= 0x000,
253	DEVSTAT_TYPE_SEQUENTIAL	= 0x001,
254	DEVSTAT_TYPE_PRINTER	= 0x002,
255	DEVSTAT_TYPE_PROCESSOR	= 0x003,
256	DEVSTAT_TYPE_WORM	= 0x004,
257	DEVSTAT_TYPE_CDROM	= 0x005,
258	DEVSTAT_TYPE_SCANNER	= 0x006,
259	DEVSTAT_TYPE_OPTICAL	= 0x007,
260	DEVSTAT_TYPE_CHANGER	= 0x008,
261	DEVSTAT_TYPE_COMM	= 0x009,
262	DEVSTAT_TYPE_ASC0	= 0x00a,
263	DEVSTAT_TYPE_ASC1	= 0x00b,
264	DEVSTAT_TYPE_STORARRAY	= 0x00c,
265	DEVSTAT_TYPE_ENCLOSURE	= 0x00d,
266	DEVSTAT_TYPE_FLOPPY	= 0x00e,
267	DEVSTAT_TYPE_MASK	= 0x00f,
268	DEVSTAT_TYPE_IF_SCSI	= 0x010,
269	DEVSTAT_TYPE_IF_IDE	= 0x020,
270	DEVSTAT_TYPE_IF_OTHER	= 0x030,
271	DEVSTAT_TYPE_IF_MASK	= 0x0f0,
272	DEVSTAT_TYPE_PASS	= 0x100
273} devstat_type_flags;
274.Ed
275.Pp
276Devices have a priority associated with them, which controls roughly where
277they are placed in the
278.Nm devstat
279list.  The priorities are as follows:
280.Bd -literal -offset indent
281typedef enum {
282	DEVSTAT_PRIORITY_MIN	= 0x000,
283	DEVSTAT_PRIORITY_OTHER	= 0x020,
284	DEVSTAT_PRIORITY_PASS	= 0x030,
285	DEVSTAT_PRIORITY_FD	= 0x040,
286	DEVSTAT_PRIORITY_WFD	= 0x050,
287	DEVSTAT_PRIORITY_SA	= 0x060,
288	DEVSTAT_PRIORITY_OCD	= 0x070,
289	DEVSTAT_PRIORITY_WCD	= 0x080,
290	DEVSTAT_PRIORITY_CD	= 0x090,
291	DEVSTAT_PRIORITY_WD	= 0x100,
292	DEVSTAT_PRIORITY_DA	= 0x110,
293	DEVSTAT_PRIORITY_CCD	= 0x120,
294	DEVSTAT_PRIORITY_MAX	= 0xfff
295} devstat_priority;
296.Ed
297.Pp
298Each device has associated with it flags to indicate what operations are
299supported or not supported.  The
300.Va devstat_support_flags
301values are as follows:
302.Bl -tag -width DEVSTAT_NO_ORDERED_TAGS
303.It DEVSTAT_ALL_SUPPORTED
304Every statistic type is supported by the device.
305.It DEVSTAT_NO_BLOCKSIZE
306This device does not have a blocksize.
307.It DEVSTAT_NO_ORDERED_TAGS
308This device does not support ordered tags.
309.It DEVSTAT_BS_UNAVAILABLE
310This device supports a blocksize, but it is currently unavailable.  This
311flag is most often used with removable media drives.
312.El
313.Pp
314Transactions to a device fall into one of three categories, which are
315represented in the
316.Va flags
317passed into
318.Fn devstat_end_transaction .
319The transaction types are as follows:
320.Bd -literal -offset indent
321typedef enum {
322	DEVSTAT_NO_DATA	= 0x00,
323	DEVSTAT_READ	= 0x01,
324	DEVSTAT_WRITE	= 0x02
325} devstat_trans_flags;
326.Ed
327.Pp
328There are four possible values for the
329.Va tag_type
330argument to
331.Fn devstat_end_transaction :
332.Bl -tag -width DEVSTAT_TAG_ORDERED
333.It DEVSTAT_TAG_SIMPLE
334The transaction had a simple tag.
335.It DEVSTAT_TAG_HEAD
336The transaction had a head of queue tag.
337.It DEVSTAT_TAG_ORDERED
338The transaction had an ordered tag.
339.It DEVSTAT_TAG_NONE
340The device doesn't support tags.
341.El
342.Pp
343The tag type values correspond to the lower four bits of the
344.Tn SCSI
345tag definitions.  In CAM, for instance, the
346.Va tag_action
347from the CCB is ORed with 0xf to determine the tag type to pass in to
348.Fn devstat_end_transaction .
349.Pp
350There is a macro,
351.Dv DEVSTAT_VERSION
352that is defined in
353.Aq sys/devicestat.h .
354This is the current version of the
355.Nm
356subsystem, and it should be incremented each time a change is made that
357would require recompilation of userland programs that access
358.Nm
359statistics.  Userland programs use this version, via the
360.Va kern.devstat.version
361.Nm sysctl
362variable to determine whether they are in sync with the kernel
363.Nm
364structures.
365.Sh SEE ALSO
366.Xr systat 1 ,
367.Xr devstat 3 ,
368.Xr iostat 8 ,
369.Xr rpc.rstatd 8 ,
370.Xr vmstat 8
371.Sh HISTORY
372The
373.Nm
374statistics system appeared in
375.Fx 3.0 .
376.Sh AUTHORS
377Kenneth Merry
378.Aq ken@FreeBSD.ORG
379.Sh BUGS
380There may be a need for
381.Fn spl
382protection around some of the
383.Nm
384list manipulation code to insure, for example, that the list of devices
385is not changed while someone is fetching the
386.Va kern.devstat.all
387.Nm sysctl
388variable.
389.Pp
390It is impossible with the current
391.Nm
392architecture to accurately measure time per transaction.  The only feasible
393way to accurately measure time per transaction would be to record a
394timestamp for every transaction.  This measurement is probably not
395worthwhile for most people as it would adversely affect the performance of
396the system and cost space to store the timestamps for individual
397transactions.
398