Linux Kernel(2.6)の実装に関するメモ書き

I/Oスケジューラ


1. 概要

ブロックI/O要求のスケジュールを行いI/Oを効率化する。Linux2.6から導入された。

スケジューラには表1に示す4種類がある。デフォルトではAnticipatoryスケジューラが使用される(RedHatではCFQがデフォルトらしい)。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

2. RequestQueue

デバイスドライバは、初期化時にblk_init_queue()によってブロックI/O要求を受け付けるRequestQueue作成する。スケジューリングはRequestQueue毎に行われる。

3. Elevator

I/Oスケジューラの実体。I/Oスケジューラ種別に非依存な部分を実装しており(ファイルシステムでいうVFS的なもの)、ここから、各スケジューラの処理が呼び出される。

RequestQueueにはElevatorが関連づけられる。ブロックI/OのRequestは一旦Elevatorに入れられて、スケジューリングされた後、Dispatchされる。DispatchされたRequestはRequestQueueに入れられてデバイスドライバがI/Oを実行していく(図1)。



図1 Requestの流れ

request_fn - ドライバのI/O Request処理ルーチン
blk_init_queue()でRequestQueueを作成する時に指定する。

このルーチンはelv_next_request()でElevatorのRequestをDispatchしてRequestQueueに入れてI/Oを実行していく。

Unplug時、I/O完了時に呼ばれる。
他にもスケジューラ個別のタイミングで呼ばれることがある(Anticipatoryスケジューラの場合はAnticipation終了時に呼び出される)。

4. Elevatorとのインタフェース

Elevator(I/Oスケジューラ)へのアクセスルーチン

elv_merge(q,req,bio)
bioを既存のRequestにMergeできるかチェックする。Merge可能ならMerge先のRequestをreqに返す。

elv_latter_request(q,rq)
Elevator内のrqの次のRequestを取得

elv_next_request(q)
RequestQueue(q->queue_head)からRequestを取得する。空だったなら、.elevator_dispatch_fn()を呼び出し、Elevator内のRequestをDispatchしてからそれを返す。どのRequestがDispatchされるかはI/Oスケジューラ次第。デバイスドライバが実行するRequestを取得するのに使う。また、Unplug時にRequestを取得するのにも使う。

elv_add_request(q, req, where, plug)
RequestをElevatorに追加

elv_completed_request()
I/O完了時にコールされる (実際は__blk_put_request()からのみコール)

elv_insert(q,rq,where)
RequestQueueのwhereで指定した位置にRequestを入れる。
elv_add_request()の内部ルーチン。

elv_dispatch_sort(q,rq)
RequestをDispatchしてRequestQueue(q->queue_head)に入れる。


最終更新 2006/07/26 12:37:11 - kztomita
(2006/07/11 18:14:39 作成)
添付ファイル
elevator.png - kztomita


リンク
最近更新したページ
検索