※以下は個人的なメモです。最新の正確な情報はAWSの公式ドキュメントなどを参照してください。
疑問点
EC2 のドキュメントで xen_blkfront.max=256 が推奨されているが、このパラメータは何を意味するのか?
4.2 以降のすべての Linux カーネルの場合、st1 ボリュームまたは sc1 ボリュームで最大スループットを得るには、xen_blkfront.max パラメータを 256 に設定することをお勧めします。このパラメータは、OS の起動コマンドラインで設定できます。たとえば、Amazon Linux AMI では、/boot/grub/menu.lst に記述されている GRUB 設定で kernel 行の末尾に追加できます。
Linux インスタンスの Amazon EBS ボリュームのパフォーマンス - Amazon Elastic Compute Cloud
調査結果
- Xen ではゲストとドライバドメイン間でのI/Oデータは共有メモリページ(1ページ=4KB)を介してやり取りする。
- リングにI/Oリクエスト構造体が格納され、そのうち Segment にデータの実体が格納されていた。
- Linux Kernel 3.11 以降、VirtIO protocol にインスパイアされて "Xen indirect descriptors implementation" では Segment にデータの実体を持つのではなく共有メモリページへのポインタにする事でリングで管理可能な共有メモリページが大きくなった。
- 結果、同時にI/O可能なデータ量が1.4MBから512MBに上がった(xen_blkfront.max=256に設定した場合)。
- I/Oリクエストあたりの最大セグメント数は xen_blkfront.max で指定でき、デフォルト 32、最大 256。
- ゲストとドライバドメインの両方のバージョンの3.11以上でないと使えない。
- Before: 1.4MB = 44KB(4KB * 11) * 32
struct blkif_request { uint8_t operation; uint8_t nr_segments; blkif_vdev_t handle; uint64_t id; blkif_sector_t sector_number; struct blkif_request_segment { grant_ref_t gref; uint8_t first_sect, last_sect; } seg[11]; ★ };
- After: 512MB = 16MB (4KB * 4096) * 32
struct blkif_request_indirect { uint8_t operation; uint8_t indirect_op; uint16_t nr_segments; uint64_t id; blkif_sector_t sector_number; blkif_vdev_t handle; uint16_t _pad2; grant_ref_t indirect_grefs[8]; }; struct blkif_request_segment_aligned { grant_ref_t gref; uint8_t first_sect, last_sect; uint16_t _pad; };