ablog

不器用で落着きのない技術者のメモ

RHEL 5.3 on Xen で grub.conf でI/Oスケジューラに何を指定しても noop になってしまう

Bug 498461 – I/O scheduler setting via elevator kernel option not picked up by Xen guest
に面白い情報があったのでまとめてみた。

まとめ

現象
  • Xen のゲストOS(Dom-U)の /boot/grub/grub.conf でI/Oスケジューラを設定して再起動しても、常に noop になる。
  • 準仮想化(ParaVirtualization)モードで発生し、完全仮想化(FullVirtualization)モードでは発生しない。
再現方法
  • 設定変更前のI/Oスケジューラを確認する。
guest% cat /sys/block/xvda/queue/scheduler
[noop] anticipatory deadline cfq

↑「noop」になっている。

  • /boot/grub/grub.conf に「noop」以外のI/Oスケジューラを設定する。「cfq」にしてみる。
guest% vi /boot/grub/grub.conf 
(中略)
        kernel /boot/vmlinuz-2.6.18-128.el5 ro root=LABEL=/ rhgb quiet elevator=cfq
  • ゲストOSを再起動する。
host% xm reboot vm01
  • 設定変更後のI/Oスケジューラを確認する。
guest% cat /sys/block/xvda/queue/scheduler
[noop] anticipatory deadline cfq

「cfq」に設定したのに「noop」になっている。

原因
  • バグ。
  • /boot/grub/grub.conf の設定に関わらずI/Oスケジューラが noop になるようハードコードされているため。

While one could argue that the driver's behavior is expected (after all
"elevator=cfq" is the default and should not have any effect), the
do-what-I-mean behavior requested by the customer is logical and this
is what the patch implements.

The patch does not change the default scheduler. It just makes the
existing knob affect blkfront.

...

diff --git a/drivers/xen/blkfront/vbd.c b/drivers/xen/blkfront/vbd.c

...

@@ -216,7 +218,10 @@ xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
 	if (rq == NULL)
 		return -1;
 
-	elevator_init(rq, "noop");
+	/* Always respect the user's explicitly chosen elevator, but otherwise
+	   pick a different default than CONFIG_DEFAULT_IOSCHED.  */
+	if (!*chosen_elevator)
+		elevator_init(rq, "noop");
 
 	/* Hard sector size and max sectors impersonate the equiv. hardware. */
 	blk_queue_hardsect_size(rq, sector_size);
https://bugzilla.redhat.com/attachment.cgi?id=364459&action=diff
  • なぜ、バグというよりこういう仕様にしていたかというと、ゲストOS(Dom-U)でI/OスケジューラでI/O要求を並び替えても無駄だから。なぜ、無駄かというと、ホストOS(Dom-0)で複数のゲストOS(Dom-U)I/O要求の並び替えをやり直すから。ゲストOS(Dom-U)のI/Oスケジューラが noop (No Operation)、つまり何もしないほうが、CPUを無駄に使わないし、下のレイヤー(Dom-0)に速くI/O要求を渡すことができる。

it's an appropriate default.

everything that virtualizes the IO benefits from using NOOP scheduler.
the point is that any (re)ordering done by the guest would be useless
when the underlying layers (Dom0 in this case, a SAN block device in
others) mangle the IO requests from several guests. not only you save
CPU cycles by not trying to be clever on the DomU, but also pushing
the requests as early as possible to the lower layer, the best
optimisations can be done at that layer.

Xen - User - Default disk I/O scheduler in linux guest
回避策
  • ゲストOS起動後にI/Oスケジューラを変更する。
geust% echo cfq > /sys/block/xvda/queue/scheduler
  • ゲストOS起動時に自動設定したい場合は、/etc/rc.local にI/Oスケジューラを変更する行を追記するなどする。
guest% vi /etc/rc.local                                                                                                                                 
#!/bin/sh
(中略)
echo cfq > /sys/block/xvda/queue/scheduler
根本対処
補足
ゲストOS/ホストOS ゲストOSのI/Oスケジューラ ホストOSのI/Oスケジューラ ddの所要時間(real)
ホストOS - cfq 2.013
ゲストOS noop cfq 2.246
    • RAID5
ゲストOS/ホストOS ゲストOSのI/Oスケジューラ ホストOSのI/Oスケジューラ ddの所要時間(real)
ホストOS - cfq 3.131
ホストOS - deadline 3.292
ゲストOS noop cfq 10.190
ゲストOS noop deadline 10.817
ゲストOS cfq cfq 6.601
ゲストOS cfq deadline 6.572
  • ホストOS(Dom-0)から xm block-attach でゲストOS(Dom-U)にブロックデバイスを直接渡したとき、ゲストOS(Dom-U)側のI/Oスケジューラーの挙動は同じなのかという疑問がある。
    • データ保存形式がファイルベースの場合とパーティションベースの場合でゲストOS(Dom-U)側のスケジューラーの挙動は同じなのかどうかという疑問。
    • 同じではないかと思う。I/Oスケジューラの挙動はデータ保存形式ではなく、準仮想化か完全仮想化かで決まるのではないかと思う。