CFQ IOスケジューラのコードを見てみる。
LinuxのDiskIO用のスケジューラとして、CFQ IOスケジューラがある。
2.6.34から帯域制御が入ったので、ちょっとコードを見てみた。
大雑把に言うと、デバイスごとにスケジューラを設定し、プロセスグループごとにWeightを考慮してブロックキューを振り分けている。
そして、処理時間は、プロセスグループごとにvdisktimeで積算されており、値の一番小さいものから実行する。なお、時刻としては、jiffiesを用いている。
とはいえ、weightの取れる範囲が100から1000と狭いことや、帯域を保障しているわけでもないから、帯域制御としては基本的な機能が入っているだけともいえる。
これは、サーバ単体で見た話であり、データセンター単位で見ると、Fibre ChannelやiSCSI経由でストレージが接続されるので、
ストレージ側でも制御できてしまう。このため、OSに帯域制御が入らなければならないという理由もない。
- 構造体
- cfq_data
- cfq_group(CFQの一塊。これをベースに帯域の割付を行う。)
- per cgroup per device grouping structure
- weight
- vdisktime
- cfq_queue(各IOリクエスト)
- Per process-grouping structure
- pid
- 関数
- cfq_group_service_tree_add ランキュー組み込み時の処理を行う。(cfqg->vdisktimeの初期化)
- cfq_slice_expired ランキュータイムアウト時の処理を行う。(cfqg->vdisktimeの加算)
- cfq_schedule_dispatch ランキューの切り替えを行う。
- cfq_idle_slice_timer アイドル時の処理を定期的に行う。
- いうまでもなく、red-black tree (rb-tree)を知っておくとコードを読み易くなる。
- もう少し外枠なら、多少古いが以下が詳しい。