devstat(9)
NAME
- devstat, devstat_add_entry, devstat_end_transaction, devstat_end_transaction_bio, devstat_remove_entry, devstat_start_transaction - kernel interface for keeping de
 - vice statistics
 
SYNOPSIS
#include <sys/devicestat.h> void devstat_add_entry(struct devstat *ds, const char *dev_name, int unit_number, u_int32_t block_size, devstat_support_flags flags, devstat_type_flags device_type, devstat_priority priority); void devstat_remove_entry(struct devstat *ds); void devstat_start_transaction(struct devstat *ds); void devstat_end_transaction(struct devstat *ds, u_int32_t bytes, devstat_tag_type tag_type, devstat_trans_flags flags); void devstat_end_transaction_bio(struct devstat *ds, struct bio *bp);
DESCRIPTION
- The  devstat  subsystem is 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 ker - nel portion of
the devstat code. Instead, that is left for user programs - to handle.
 - devstat_add_entry() registers a device with the devstat sub
 - system.  The
caller is expected to have already allocated and zeroed the - devstat
structure before calling this function. devstat_add_entry() - takes several arguments:
 - ds The devstat structure, allocated and zeroed by
 - the client.
 - dev_name The device name, e.g. da, cd, sa.
 - unit_number Device unit number.
 - 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 devstat - list, it should
be set to 0. - flags Flags indicating operations supported or not
 - supported by
 - the device. See below for details.
 - device_type The device type. This is broken into three
 - sections: base
 - device type (e.g. direct access, CDROM, sequen
 - tial access),
interface type (IDE, SCSI or other) and a pass - through flag
to indicate pas-through devices. See below for - a complete
list of types. - priority The device priority. The priority is used to
 - determine how
 - devices are sorted within devstat's list of de
 - vices.
Devices are sorted first by priority (highest - to lowest),
and then by attach order. See below for a com - plete list of
available priorities. - devstat_remove_entry() removes a device from the devstat
 - subsystem.  It
takes the devstat structure for the device in question as an - argument.
The devstat generation number is incremented and the number - of devices is
decremented. - devstat_start_transaction() registers the start of a trans
 - action with the
devstat subsystem. The busy count is incremented with each - transaction
start. When a device goes from idle to busy, the system up - time is
recorded in the start_time field of the devstat structure. - devstat_end_transaction() registers the end of a transaction
 - with the
devstat subsystem. It takes four arguments: - ds The devstat structure for the device in question.
 - bytes The number of bytes transferred in this transac
 - tion.
 - tag_type Transaction tag type. See below for tag types.
 - flags Transaction flags indicating whether the transac
 - tion was a
 - read, write, or whether no data was transferred.
 - devstat_end_transaction_bio() is a wrapper for
 - devstat_end_transaction()
which pulls all the information from a struct bio which is - ready for
biodone(). - The devstat structure is composed of the following fields:
 - dev_links Each devstat structure is placed in a
 - linked list when
 - it is registered. The dev_links field
 - contains a
pointer to the next entry in the list of - devstat
structures. - 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. - device_name The device name is a text string given by
 - the regis
 - tering driver to identify itself. (e.g.
 - ``da'',
``cd'', ``sa'', etc.) - unit_number The unit number identifies the particular
 - instance of
 - the peripheral driver in question.
 - 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 elimi - nate the
counter wrap that would come very quickly - on some systems if 32 bit integers were used.
 - bytes_read This is the number of bytes that have
 - been read from
 - the device.
 - bytes_freed This is the number of bytes that have
 - been
 - freed/erased on the device.
 - num_reads This is the number of reads from the de
 - vice.
 - num_writes This is the number of writes to the de
 - vice.
 - num_frees This is the number of free/erase opera
 - tions on the
 - device.
 - num_other This is the number of transactions to the
 - device which
 - are neither reads or writes. For in
 - stance, SCSI
drivers often send a test unit ready com - mand to SCSI
devices. The test unit ready command - does not read or
write any data. It merely causes the de - vice to return
its status. - busy_count This is the current number of outstanding
 - transactions
 - for the device. This should never go be
 - low zero, and
on an idle device it should be zero. If - either one of
these conditions is not true, it indi - cates a problem
in the way devstat_start_transaction() - and
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. - block_size This is the block size of the device, if
 - the device
 - has a block size.
 - tag_types This is an array of counters to record
 - the number of
 - various tag types that are sent to a de
 - vice.  See
below for a list of tag types. - dev_creation_time This is the time, as reported by
 - getmicrotime() that
 - the device was registered.
 - busy_time This is the amount of time that the de
 - vice busy count
 - has been greater than zero. This is only
 - updated when
the busy count returns to zero. - start_time This is the time, as reported by
 - getmicrouptime() that
 - the device busy count went from zero to
 - one.
 - last_comp_time This is the time as reported by
 - getmicrouptime() that
 - a transaction last completed. It is used
 - along with
start_time to calculate the device busy - time.
 - 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.
 - 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. - priority This is the priority. This is the first
 - parameter
 - used to determine where to insert a de
 - vice in the
devstat list. The second parameter is - attach order.
See below for a list of available priori - ties.
 - Each device is given a device type. Pass-through devices
 - have the same
underlying device type and interface as the device they pro - vide an interface for, but they also have the pass-through flag set. The
 - base device
types are identical to the SCSI device type numbers, so with - SCSI peripherals, the device type returned from an inquiry is usually
 - ORed with the
SCSI interface type and the pass-through flag if appropri - ate.  The device
type flags are as follows: 
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;
 - Devices have a priority associated with them, which controls
 - roughly
where they are placed in the devstat list. The priorities - are as follows:
 
typedef enum {DEVSTAT_PRIORITY_MIN = 0x000,
DEVSTAT_PRIORITY_OTHER = 0x020,
DEVSTAT_PRIORITY_PASS = 0x030,
DEVSTAT_PRIORITY_FD = 0x040,
DEVSTAT_PRIORITY_WFD = 0x050,
DEVSTAT_PRIORITY_TAPE = 0x060,
DEVSTAT_PRIORITY_CD = 0x090,
DEVSTAT_PRIORITY_DISK = 0x110,
DEVSTAT_PRIORITY_ARRAY = 0x120,
DEVSTAT_PRIORITY_MAX = 0xfff- } devstat_priority;
 - Each device has associated with it flags to indicate what
 - operations are
supported or not supported. The devstat_support_flags val - ues are as follows:
 - DEVSTAT_ALL_SUPPORTED Every statistic type is supported
 - by the device.
 - DEVSTAT_NO_BLOCKSIZE This device does not have a block
 - size.
 - DEVSTAT_NO_ORDERED_TAGS This device does not support or
 - dered tags.
 - DEVSTAT_BS_UNAVAILABLE This device supports a blocksize,
 - but it is cur
 - rently unavailable. This flag is
 - most often
used with removable media drives. - Transactions to a device fall into one of three categories,
 - which are
represented in the flags passed into - devstat_end_transaction(). The transaction types are as follows:
 
typedef enum {DEVSTAT_NO_DATA = 0x00,
DEVSTAT_READ = 0x01,
DEVSTAT_WRITE = 0x02,
DEVSTAT_FREE = 0x03- } devstat_trans_flags;
 - There are four possible values for the tag_type argument to devstat_end_transaction():
 - DEVSTAT_TAG_SIMPLE The transaction had a simple tag.
 - DEVSTAT_TAG_HEAD The transaction had a head of queue
 - tag.
 - DEVSTAT_TAG_ORDERED The transaction had an ordered tag.
 - DEVSTAT_TAG_NONE The device does not support tags.
 - The tag type values correspond to the lower four bits of the
 - SCSI tag
definitions. In CAM, for instance, the tag_action from the - CCB is ORed
with 0xf to determine the tag type to pass in to
devstat_end_transaction(). - There is a macro, DEVSTAT_VERSION that is defined in This is
 - the current
version of the devstat subsystem, and it should be incre - mented each time
a change is made that would require recompilation of user - land programs
that access devstat statistics. Userland programs use this - version, via
the kern.devstat.version sysctl variable to determine - whether they are in
sync with the kernel devstat structures. 
SEE ALSO
systat(1), devstat(3), iostat(8), rpc.rstatd(8), vmstat(8)
HISTORY
The devstat statistics system appeared in FreeBSD 3.0.
AUTHORS
Kenneth Merry <ken@FreeBSD.org>
BUGS
- There  may be a need for spl() protection around some of the
 - devstat list
manipulation code to insure, for example, that the list of - devices is not
changed while someone is fetching the kern.devstat.all - sysctl variable.
 - It is impossible with the current devstat architecture to
 - accurately measure time per transaction. The only feasible way to accu
 - rately measure
time per transaction would be to record a timestamp for ev - ery 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. - BSD May 22, 1998