I/Oスケジューラ
Rev.14を表示中。最新版はこちら。
概要
ブロックI/O要求のスケジュールを行いI/Oを効率化する。Linux2.6から導入された。スケジューラには表1に示す4種類がある。デフォルトではAnticipatoryスケジューラが使用される。chosen_elevator[]には選択されたI/Oスケジューラの名前が格納される。I/Oスケジューラはシステムで1つ。混在はできない。
表1 I/Oスケジューラの種類
スケジューラ | 関連config | ElevatorType |
---|---|---|
Anticipatory(Default) | CONFIG_IOSCHED_AS | iosched_as |
Deadline | CONFIG_IOSCHED_DEADLINE | iosched_deadline |
CFQ | CONFIG_IOSCHED_CFQ | iosched_cfq |
NOOP | CONFIG_IOSCHED_NOOP | elevator_noop |
RequestQueue
デバイスドライバは、初期化時にblk_init_queue()によってブロックI/O要求を受け付けるRequestQueue作成する。スケジューリングはRequestQueue毎に行われる。Elevator
RequestQueueにはElevatorが関連づけられる。I/O Requestを発行すると、RequestはElevatorの中に入れられ、スケジューラ
RequestQueueへのアクセス(空か否かのチェック、次のRequestの取得)はElevatorを通して行われる。
Elevatorとのインタフェース
Elevatorはシステムが使用しているI/Oスケジューラの種類に応じたアルゴリズムでRequestQueueへアクセスする。以下はRequestQueueへアクセスするためのElevatorルーチンの一部。
elv_merge(q,req,bio)
bioを既存のRequestにMergeできるかチェックする。Merge可能ならMerge先のRequestをreqに返す。
elv_latter_request(q,rq)
RequestQueue内のrqの次のRequestを取得
elv_next_request(q)
次にデバイスに発行するRequestをRequestQueueから取得する。どのRequestを返すかはI/Oスケジューラ次第。デバイスドライバが実行するRequestを取得するのに使う。Unplug時にRequestを取得するのに使う。
elv_add_request(q, req, where, plug)
RequestをRequestQueueに追加
elv_completed_request()
I/O完了時にコールされる (実際は__blk_put_request()からのみコール)
elv_insert(q,rq,where)
RequestQueueのwhereで指定した位置にRequestを入れる。
elv_add_request()の内部ルーチン。
elv_add_request()の内部ルーチン。
elv_dispatch_sort(q,rq)
RequestをDispatchQueue(q->queue_head)に入れる。