スポンサーリンク

DEVSTAT(9) FreeBSD カーネル開発者マニュアル DEVSTAT(9)

名称

devstat, devstat_add_entry, devstat_end_transaction, devstat_end_transaction_bio, devstat_remove_entry, devstat_start_transaction − デバイス統計の記録のためのカーネルインタ フェース

書式

#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);

解説

devstat サブシステムは、その名称が暗示する様に、デバイス統計を記録するた めのインタフェースです。この目的は、適度に詳細な統計情報を記録しつつ、記 録に使用する CPU 時間を最小とするというものです。従って、 devstat のコー ドのカーネル内の部分では、実際の統計的な計算は行なわれていません。代わり に、これはユーザプログラムが取り扱うように残されています。

devstat_add_entry() は devstat サブシステムにデバイスを登録します。呼び出 し側はこの関数の呼び出しの前に、既に割当てられ 0 でクリアされた devstat 構造体を持っていることを期待されています。 devstat_add_entry() は幾つかの 引数を取ります。

       ds

クライアントによって割当てられ 0 でクリアされた、 devstat 構 造体です。

dev_name
デバイスの名前です。例えば da, cd, sa です。

unit_number
デバイスユニット番号です。

block_size
サポートされている場合には、デバイスのブロックサイズです。デ バイスがブロックサイズをサポートしていない場合、または devstat リストにそのデバイスが追加される時点ではブロックサイ ズが判っていない場合には、 0 に設定されるべきです。

flags
デバイスによって操作がサポートされているかサポートされていな いかを示すフラグです。詳細は以下を参照してください。

device_type
デバイスの型です。これは 3 つの部分、基本的なデバイスの型 ( 例えば、直接アクセス、CDROM、順次アクセス)、インタフェースの 型 (IDE, SCSI またはその他) および通過するデバイスを示すため のパススルーフラグに、分割されます。完全な型のリストは以下を 参照してください。

priority
デバイスの優先度です。優先度はデバイスの devstat リストの中 でどのようにデバイスを並び替えるかを決定するために使用されま す。デバイスは最初に優先度 (高い方から低い方) によって、それ からアタッチされた順番によって並び替えられます。利用可能な優 先度の完全なリストは以下を参照してください。

devstat_remove_entry() は devstat サブシステムからデバイスを削除します。 これは引数として当のデバイスの devstat 構造体を取ります。 devstat 世代番 号は増やされデバイスの数は減らされます。

devstat_start_transaction() は devstat サブシステムに処理の開始を登録しま す。個々の処理の開始でビジーカウントが増やされます。デバイスがアイドルか らビジーに移ったときには、システム uptime が devstat 構造体の start_time フィールドに記録されます。

devstat_end_transaction() は devstat サブシステムに処理の終了を登録しま す。これは 4 つの引数を取ります。

ds
当のデバイスのための devstat 構造体です。

bytes
この処理で転送されたバイト数です。

tag_type
処理のタグの型です。タグの型は以下を参照してください。

flags
その処理が読込みだったのか、書込みだったのか、または転送された データがなかったのかを示す処理フラグです。

devstat_end_transaction_bio() は、biodone() の準備が整っている struct bio からすべての情報を引き出すための、 devstat_end_transaction() のためのラッ パです。

devstat 構造体は以下のフィールドで構成されています。

dev_links
個々の devstat は登録されたときにリンクされたリストに 置かれます。 dev_links フィールドには devstat 構造体の リストの中の次のエントリへのポインタが入ります。

device_number
デバイス番号は、個々のデバイスのための一意な識別子で す。デバイス番号は、個々の新しいデバイスが登録されるご とに増やされます。現在はデバイス番号は単なる 32 ビット 整数ですが、40 億個を超えるデバイス到着イベントを持つ システムがあれば、拡張するかもしれません。

device_name
デバイス名称はドライバ登録によって与えられる文字列であ り、自分自身を識別するために使用できます。 (例えば ‘‘da’’, ‘‘cd’’, ‘‘sa’’, など)。

unit_number
ユニット番号は当の周辺装置のドライバ特有の実体を識別し ます。

bytes_written
これはそのデバイスに既に書込まれたバイト数です。この数 は現在は符号なし 64 ビット整数です。 32 ビットの整数を 使った場合にはシステムによってはすぐにカウンタが一回り してしまうという問題を、これにより回避できると期待して います。

bytes_read
これはそのデバイスから既に読込まれたバイト数です。

bytes_freed
これはそのデバイス上の既に解放/消去されたバイト数で す。

num_reads
これはそのデバイスからの読込み回数です。

num_writes
これはそのデバイスへの書込み回数です。

num_frees
これはそのデバイス上の解放/消去操作の回数です。

num_other
これはそのデバイスへの読込みでも書込みでもない処理の回 数です。例えば、 SCSI ドライバはしばしばテストユニット レディコマンドを SCSI デバイスに送ります。そのテストユ ニットレディコマンドはデータを全く読込みまたは書込みま せん。これは単にその状態を返させるだけにすぎません。

busy_count
これはそのデバイスのための現在未解決の処理の数です。こ れは 0 を決して下回るべきではなく、アイドルのデバイス では 0 になるべきです。これらの状態のいずれかが真でな い場合には、クライアントのコードの devstat_start_transaction() と devstat_end_transaction() の呼び出し方に問題があること を示しています。個々の処理にはただ 1 つの処理開始イベ ントがあるべきであり、各処理に対して 1 つの処理終了イ ベントがあるべきです。

block_size
そのデバイスがブロックサイズを持っている場合には、これ はそのデバイスのブロックサイズです。

tag_types
これはデバイスに送られた様々なタグの型の数を記録するた めのカウンタの配列です。タグの型のリストは以下を参照し てください。

dev_creation_time
これはそのデバイスが登録されたときの getmicrotime() に よって報告される時間です

busy_time
これは、デバイスのビジーカウントが 0 より大きかった時 間の量です。これはビジーカウントが 0 に戻ったときにの み更新されます。

start_time
これはそのデバイスのビジーカウントが 0 から 1 に移った ときの getmicrouptime() によって報告される時間です

last_comp_time
これは処理が完全に終わったときの getmicrouptime() に よって報告される時間です。これはデバイスビジー時間を計 算するために start_time と一緒に使用されます。

flags
これらのフラグは個々のデバイスによって、どの統計測定が サポートされているのかを示します。これらのフラグは本来 は、統計を解読するユーザ側のプログラムの補助として働く ことを意図されています。

device_type
これはデバイスの型です。これは 3 つの部分から構成され ています。デバイスの型 (例えば、直接アクセス、CDROM、 順次アクセス、など)、インタフェース (IDE, SCSI または その他) および当のデバイスがパススルードライバであるか どうか、です。デバイスの型の完全なリストは以下を参照し てください。

priority
これは優先度です。これはデバイスを devstat リストの何 処に挿入するのかを決定するために使用される最初のパラ メータです。 2 番目のパラメータはアタッチの順番です。 利用可能な優先度のリストは以下を参照してください。

個々のデバイスはデバイスの型が与えられます。パススルーデバイスはインタ フェースを供給するためのデバイスと同じ基礎的なデバイスの型とインタフェー スを持ちますが、パススルーフラグも設定されています。基本のデバイスの型は SCSI のデバイス型番号と一致しています。そのため SCSI 周辺装置では、問合せ から返されたデバイスの型は、通常、 SCSI インタフェースの型ともし適切であ ればパススルーフラグで OR されます。デバイスの型のフラグは以下のとおりで す。

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;

デバイスはそれらに関連付けられた優先度を持っていて、 devstat リストのおお よそ何処に置かれるのかを制御します。優先度は以下のとおりです。

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;

個々のデバイスは何の操作がサポートされているかサポートされていないのかを 示す、それに関連付けられたフラグを持っています。 devstat_support_flags の 値は以下のとおりです。

       DEVSTAT_ALL_SUPPORTED

デバイスによって全ての統計の型がサポートされてい ます。

DEVSTAT_NO_BLOCKSIZE
このデバイスはブロックサイズを持っていません。

DEVSTAT_NO_ORDERED_TAGS
このデバイスは順序タグ (ordered tag) をサポート していません。

DEVSTAT_BS_UNAVAILABLE
このデバイスはブロックサイズをサポートしています が、現在は利用できません。このフラグはリムーバブ ルメディアのドライバでよく使用されます。

デバイスへの処理は 3 つのカテゴリのうちのいずれかに分類されます。これは devstat_end_transaction() へ渡される flags に表現されています。処理の型は 以下のとおりです。

typedef enum {

DEVSTAT_NO_DATA

= 0x00,

DEVSTAT_READ

= 0x01,

DEVSTAT_WRITE

= 0x02,

DEVSTAT_FREE

= 0x03

} devstat_trans_flags;

devstat_end_transaction() の tag_type 引数には、次の 4 つの値を指定可能で す:

       DEVSTAT_TAG_SIMPLE

その処理は単純なタグを持っていました。

DEVSTAT_TAG_HEAD
この処理はキュータグの先頭を持っていました。

DEVSTAT_TAG_ORDERED
その処理は順序タグを持っていました。

DEVSTAT_TAG_NONE
そのデバイスはタグをサポートしません。

タグの型の値は SCSI のタグの定義の下位 4 ビットと一致しています。例えば CAM では、 CCB の tag_action が 0xf と OR することにより、 devstat_end_transaction() に渡すタグの型を判定します。

<sys/devicestat.h> で DEVSTAT_VERSION マクロが定義されています。これは devstat サブシステムの現在のバージョンで、 devstat 統計にアクセスするユー ザ側プログラムの再コンパイルが要求される変更のたびに、増やされるべきで す。ユーザ側プログラムは、カーネルの devstat 構造体と同期しているかどうか を決定するために、 kern.devstat.version sysctl 変数を通してこのバージョン を使用します。

関連項目

systat(1), devstat(3), iostat(8), rpc.rstatd(8), vmstat(8)

歴史

devstat 統計システムは FreeBSD 3.0 で登場しました。

作者

Kenneth Merry ⟨ken@FreeBSD.org⟩

バグ

devstat リスト操作コード周りで spl() 保護が必要かもしれません。これは、例 えば誰かが kern.devstat.all sysctl 変数を取り出している間に、デバイスのリ ストが変更されないことを保証するためです。

現在の devstat の構造では正確に処理毎の時間を測定することが不可能です。唯 一の上手くいきそうな処理毎の正確な時間測定の方法は、処理毎にタイムスタン プを記録することです。システムのパフォーマンスおよび各個の処理のためにタ イムスタンプを保存するための空間コストに負の影響を与えるため、この測定は 恐らくは殆んどの人々には価値のないことです。

FreeBSD 10.0 May 22, 1998 FreeBSD 10.0

スポンサーリンク