Man page describing the in kernel device statistics routines.
Submitted by: "Kenneth D. Merry" <ken@plutotech.com>
This commit is contained in:
parent
1dbdc3a12e
commit
ec356481de
361
share/man/man9/devstat.9
Normal file
361
share/man/man9/devstat.9
Normal file
@ -0,0 +1,361 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1998 Kenneth D. Merry.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd May 22, 1998
|
||||
.Dt DEVSTAT 9
|
||||
.Os FreeBSD 3.0
|
||||
.Sh NAME
|
||||
.Nm devstat
|
||||
.Nd kernel interface for keeping device statistics
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/devicestat.h>
|
||||
.Ft void
|
||||
.Fo devstat_add_entry
|
||||
.Fa "struct devstat *ds"
|
||||
.Fa "char *dev_name"
|
||||
.Fa "int unit_number"
|
||||
.Fa "u_int32_t block_size"
|
||||
.Fa "devstat_support_flags flags"
|
||||
.Fa "devstat_type_flags device_type"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn devstat_remove_entry "struct devstat *ds"
|
||||
.Ft void
|
||||
.Fn devstat_start_transaction "struct devstat *ds"
|
||||
.Ft void
|
||||
.Fo devstat_end_transaction
|
||||
.Fa "struct devstat *ds"
|
||||
.Fa "u_int32_t bytes"
|
||||
.Fa "devstat_tag_type tag_type"
|
||||
.Fa "devstat_trans_flags flags"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The devstat subsystem is basically an interface for recording device
|
||||
statistics, as its name implies. The idea is to keep reasonably detailed
|
||||
statistics while utilizing a minimum amount of CPU time to record them.
|
||||
Thus, no statistical calculations are actually performed in the kernel
|
||||
portion of the
|
||||
.Nm
|
||||
code. Instead, that is left for user programs to handle.
|
||||
.Pp
|
||||
.Fn devstat_add_entry
|
||||
registers a device with the
|
||||
.Nm
|
||||
subsystem. The caller is expected to have already allocated \fBand zeroed\fR
|
||||
the devstat structure before calling this function.
|
||||
.Fn devstat_add_entry
|
||||
takes several arguments:
|
||||
.Bl -tag -width device_type
|
||||
.It ds
|
||||
The
|
||||
.Va devstat
|
||||
structure, allocated and zeroed by the client.
|
||||
.It dev_name
|
||||
The device name. e.g. da, cd, sa.
|
||||
.It unit_number
|
||||
Device unit number.
|
||||
.It block_size
|
||||
Block size of the device, if supported. If the device does not support a
|
||||
block size, or if the blocksize is unknown at the time the device is added
|
||||
to the
|
||||
.Nm
|
||||
list, it should be set to 0.
|
||||
.It flags
|
||||
Flags indicating operations supported or not supported by the device. See
|
||||
below for details.
|
||||
.It device_type
|
||||
The device type. This is broken into three sections: base device type
|
||||
(e.g. direct access, CDROM, sequential access), interface type (IDE, SCSI
|
||||
or other) and a passthrough flag to indicate pasthrough devices. See below
|
||||
for a complete list of types.
|
||||
.El
|
||||
.Pp
|
||||
.Fn devstat_remove_entry
|
||||
removes a device from the
|
||||
.Nm
|
||||
subsystem. It takes the devstat structure for the device in question as
|
||||
an argument. The
|
||||
.Nm
|
||||
generation number is incremented and the number of devices is decremented.
|
||||
.Pp
|
||||
.Fn devstat_start_transaction
|
||||
registers the start of a transaction with the
|
||||
.Nm
|
||||
subsystem. The busy count is incremented with each transaction start.
|
||||
When a device goes from idle to busy, the system uptime is recorded in the
|
||||
.Va start_time
|
||||
field of the
|
||||
.Va devstat
|
||||
structure.
|
||||
.Pp
|
||||
.Fn devstat_end_transaction
|
||||
registers the end of a transaction with the
|
||||
.Nm
|
||||
subsystem. It takes four arguments:
|
||||
.Bl -tag -width tag_type
|
||||
.It ds
|
||||
The
|
||||
.Va devstat
|
||||
structure for the device in question.
|
||||
.It bytes
|
||||
The number of bytes transferred in this transaction.
|
||||
.It tag_type
|
||||
Transaction tag type. See below for tag types.
|
||||
.It flags
|
||||
Transaction flags indicating whether the transaction was a read, write, or
|
||||
whether no data was transferred.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Va devstat
|
||||
structure is composed of the following fields:
|
||||
.Bl -tag -width dev_creation_time
|
||||
.It dev_links
|
||||
Each
|
||||
.Va devstat
|
||||
structure is placed in a linked list when it is registered. The
|
||||
.Va dev_links
|
||||
field contains a pointer to the next entry in the list of
|
||||
.Va devstat
|
||||
structures.
|
||||
.It device_number
|
||||
The device number is a unique identifier for each device. The device
|
||||
number is incremented for each new device that is registered. The device
|
||||
number is currently only a 32-bit integer, but it could be enlarged if
|
||||
someone has a system with more than four billion device arrival events.
|
||||
.It device_name
|
||||
The device name is a text string given by the registering driver to
|
||||
identify itself. (e.g.
|
||||
.Dq da ,
|
||||
.Dq cd ,
|
||||
.Dq sa ,
|
||||
etc.)
|
||||
.It unit_number
|
||||
The unit number identifies the particular instance of the peripheral driver
|
||||
in question.
|
||||
.It bytes_written
|
||||
This is the number of bytes that have been written to the device. This
|
||||
number is currently an unsigned 64 bit integer. This will hopefully
|
||||
eliminate the counter wrap that would come very quickly on some systems if
|
||||
32 bit integers were used.
|
||||
.It bytes_read
|
||||
This is the number of bytes that have been read from the device.
|
||||
.It num_reads
|
||||
This is the number of reads from the device.
|
||||
.It num_writes
|
||||
This is the number of writes to the device.
|
||||
.It num_other
|
||||
This is the number of transactions to the device which are neither reads or
|
||||
writes. For instance,
|
||||
.Tn SCSI
|
||||
drivers often send a test unit ready command to
|
||||
.Tn SCSI
|
||||
devices. The test unit ready command does not read or write any data. It
|
||||
merely causes the device to return its status.
|
||||
.It busy_count
|
||||
This is the current number of outstanding transactions for the device.
|
||||
This should never go below zero, and on an idle device it should be zero.
|
||||
If either one of these conditions is not true, it indicates a problem in
|
||||
the way
|
||||
.Fn devstat_start_transaction
|
||||
and
|
||||
.Fn devstat_end_transaction
|
||||
are being called in client code. There should be one and only one
|
||||
transaction start event and one transaction end event for each transaction.
|
||||
.It block_size
|
||||
This is the block size of the device, if the device has a block size.
|
||||
.It tag_types
|
||||
This is an array of counters to record the number of various tag types that
|
||||
are sent to a device. See below for a list of tag types.
|
||||
.It dev_creation_time
|
||||
This is the time, as reported by
|
||||
.Fn getmicrotime
|
||||
that the device was registered.
|
||||
.It busy_time
|
||||
This is the amount of time that the device busy count has been greater than
|
||||
zero. This is only updated when the busy count returns to zero.
|
||||
.It start_time
|
||||
This is the time, as reported by
|
||||
.Fn getmicrouptime
|
||||
that the device busy count went from zero to one.
|
||||
.It last_comp_time
|
||||
This is the time as reported by
|
||||
.Fn getmicrouptime
|
||||
that a transaction last completed. It is used along with
|
||||
.Va start_time
|
||||
to calculate the device busy time.
|
||||
.It flags
|
||||
These flags indicate which statistics measurements are supported by a
|
||||
particular device. These flags are primarily intended to serve as an aid
|
||||
to userland programs that decipher the statistics.
|
||||
.It device_type
|
||||
This is the device type. It consists of three parts: the device type
|
||||
(e.g. direct access, CDROM, sequential access, etc.), the interface (IDE,
|
||||
SCSI or other) and whether or not the device in question is a passthrough
|
||||
driver. See below for a complete list of device types.
|
||||
.El
|
||||
.Pp
|
||||
Each device is given a device type. Passthrough devices have the same
|
||||
underlying device type and interface as the device they provide an
|
||||
interface for, but they also have the passthrough flag set. The base
|
||||
device types are identical to the
|
||||
.Tn SCSI
|
||||
device type numbers, so with
|
||||
.Tn SCSI
|
||||
peripherals, the device type returned from an inquiry is usually ORed with
|
||||
the
|
||||
.Tn SCSI
|
||||
interface type and the passthrough flag if appropriate. The device type
|
||||
flags are as follows:
|
||||
.Bd -literal -offset indent
|
||||
typedef enum {
|
||||
DEVSTAT_TYPE_DIRECT = 0x000,
|
||||
DEVSTAT_TYPE_SEQUENTIAL = 0x001,
|
||||
DEVSTAT_TYPE_PRINTER = 0x002,
|
||||
DEVSTAT_TYPE_PROCESSOR = 0x003,
|
||||
DEVSTAT_TYPE_WORM = 0x004,
|
||||
DEVSTAT_TYPE_CDROM = 0x005,
|
||||
DEVSTAT_TYPE_SCANNER = 0x006,
|
||||
DEVSTAT_TYPE_OPTICAL = 0x007,
|
||||
DEVSTAT_TYPE_CHANGER = 0x008,
|
||||
DEVSTAT_TYPE_COMM = 0x009,
|
||||
DEVSTAT_TYPE_ASC0 = 0x00a,
|
||||
DEVSTAT_TYPE_ASC1 = 0x00b,
|
||||
DEVSTAT_TYPE_STORARRAY = 0x00c,
|
||||
DEVSTAT_TYPE_ENCLOSURE = 0x00d,
|
||||
DEVSTAT_TYPE_FLOPPY = 0x00e,
|
||||
DEVSTAT_TYPE_MASK = 0x00f,
|
||||
DEVSTAT_TYPE_IF_SCSI = 0x010,
|
||||
DEVSTAT_TYPE_IF_IDE = 0x020,
|
||||
DEVSTAT_TYPE_IF_OTHER = 0x030,
|
||||
DEVSTAT_TYPE_IF_MASK = 0x0f0,
|
||||
DEVSTAT_TYPE_PASS = 0x100
|
||||
} devstat_type_flags;
|
||||
.Ed
|
||||
.Pp
|
||||
Each device has associated with it flags to indicate what operations are
|
||||
supported or not supported. The
|
||||
.Va devstat_support_flags
|
||||
values are as follows:
|
||||
.Bl -tag -width DEVSTAT_NO_ORDERED_TAGS
|
||||
.It DEVSTAT_ALL_SUPPORTED
|
||||
Every statistic type is supported by the device.
|
||||
.It DEVSTAT_NO_BLOCKSIZE
|
||||
This device does not have a blocksize.
|
||||
.It DEVSTAT_NO_ORDERED_TAGS
|
||||
This device does not support ordered tags.
|
||||
.It DEVSTAT_BS_UNAVAILABLE
|
||||
This device supports a blocksize, but it is currently unavailable. This
|
||||
flag is most often used with removable media drives.
|
||||
.El
|
||||
.Pp
|
||||
Transactions to a device fall into one of three categories, which are
|
||||
represented in the
|
||||
.Va flags
|
||||
passed into
|
||||
.Fn devstat_end_transaction .
|
||||
The transaction types are as follows:
|
||||
.Bd -literal -offset indent
|
||||
typedef enum {
|
||||
DEVSTAT_NO_DATA = 0x00,
|
||||
DEVSTAT_READ = 0x01,
|
||||
DEVSTAT_WRITE = 0x02
|
||||
} devstat_trans_flags;
|
||||
.Ed
|
||||
.Pp
|
||||
There are four possible values for the
|
||||
.Va tag_type
|
||||
argument to
|
||||
.Fn devstat_end_transaction :
|
||||
.Bl -tag -width DEVSTAT_TAG_ORDERED
|
||||
.It DEVSTAT_TAG_SIMPLE
|
||||
The transaction had a simple tag.
|
||||
.It DEVSTAT_TAG_HEAD
|
||||
The transaction had a head of queue tag.
|
||||
.It DEVSTAT_TAG_ORDERED
|
||||
The transaction had an ordered tag.
|
||||
.It DEVSTAT_TAG_NONE
|
||||
The device doesn't support tags.
|
||||
.El
|
||||
.Pp
|
||||
The tag type values correspond to the lower four bits of the
|
||||
.Tn SCSI
|
||||
tag definitions. In CAM, for instance, the
|
||||
.Va tag_action
|
||||
from the CCB is ORed with 0xf to determine the tag type to pass in to
|
||||
.Fn devstat_end_transaction .
|
||||
.Pp
|
||||
There is a macro,
|
||||
.Dv DEVSTAT_VERSION
|
||||
that is defined in
|
||||
.Aq sys/devicestat.h .
|
||||
This is the current version of the
|
||||
.Nm
|
||||
subsystem, and it should be incremented each time a change is made that
|
||||
would require recompilation of userland programs that access
|
||||
.Nm
|
||||
statistics. Userland programs use this version, via the
|
||||
.Va kern.devstat.version
|
||||
.Nm sysctl
|
||||
variable to determine whether they are in sync with the kernel
|
||||
.Nm
|
||||
structures.
|
||||
.Sh SEE ALSO
|
||||
.Xr systat 1 ,
|
||||
.Xr devstat 3 ,
|
||||
.Xr iostat 8 ,
|
||||
.Xr rpc.rstatd 8 ,
|
||||
.Xr vmstat 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
statistics system appeared in
|
||||
.Fx 3.0 .
|
||||
.Sh AUTHORS
|
||||
Kenneth Merry
|
||||
.Aq ken@FreeBSD.ORG
|
||||
.Sh BUGS
|
||||
There may be a need for
|
||||
.Fn spl
|
||||
protection around some of the
|
||||
.Nm
|
||||
list manipulation code to insure, for example, that the list of devices
|
||||
is not changed while someone is fetching the
|
||||
.Va kern.devstat.all
|
||||
.Nm sysctl
|
||||
variable.
|
||||
.Pp
|
||||
It is impossible with the current
|
||||
.Nm
|
||||
architecture to accurately measure time per transaction. The only feasible
|
||||
way to accurately measure time per transaction would be to record a
|
||||
timestamp for every transaction. This measurement is probably not
|
||||
worthwhile for most people as it would adversely affect the performance of
|
||||
the system and cost space to store the timestamps for individual
|
||||
transactions.
|
Loading…
Reference in New Issue
Block a user