virtio balloon driver解説

最新のLinuxカーネルQEMU/KVMを使えば、特にトラブルもなくゲストメモリを動的に増減(memory ballooning)できるようになりました。

QEMU/KVMにおけるmemory ballooningのメカニズムをちょっとだけご紹介します。

概要

  • ゲストで使用されていないメモリを、ゲストカーネルのballoonドライバがホストへ返却,もしくはホストへ返却されたメモリをゲストへ返すことができる
  • ホスト主導で行なわれ,(いまのところ)ゲスト主導でメモリを返却することはできない
  • qemu-kvmの引数で指定したメモリ(もしくはデフォルトのメモリ)量よりゲストメモリを大きくすることはできない
  • virtioで実装されている
  • ゲストは(いまのところ)Linuxのみで,ゲストカーネルにvirtio_balloon.koドライバがロードされていなければならない
  • KVMは必須ではない

virtio balloonドライバの使い方

  • linux-2.6.27 guest/host & kvm-77を用意する
  • qemuを起動しqemuコンソールでballoonコマンドを発行する
(qemu) info balloon
balloon: actual=384
(qemu) balloon 256
(qemu) info balloon
balloon: actual=256
(qemu) balloon 384
(qemu) info balloon
balloon: actual=384
(qemu)
[root@localhost ~]# free
            total       used       free     shared    buffers     cached
Mem:        384768      48796     335972          0      10684      25128
-/+ buffers/cache:      12984     371784
Swap:      1015800          0    1015800
[root@localhost ~]# free
            total       used       free     shared    buffers     cached
Mem:        253696      48548     205148          0      10684      25128
-/+ buffers/cache:      12736     240960
Swap:      1015800          0    1015800
[root@localhost ~]# free
            total       used       free     shared    buffers     cached
Mem:        384768      48768     336000          0      10684      25128
-/+ buffers/cache:      12956     371812
Swap:      1015800          0    1015800

balloonデバイス&ドライバの初期化

  • [host] PCエミュレータ(qemu)にballoonデバイスを登録する
  • [guest] balloonデバイスが検出されれば初期化する
    • その際"vballoon"という名前のカーネルスレッドを生成する
      • vballoonはvirtio pciのconfigの変化をトリガに起床する(wait_event_interruptible())
    • inflate, deflateそれぞれにvirtqueueを用意する

ballooning処理の流れ

  • [host] qemu commandでballoonサイズを指定する
    • 値の受け渡しはvirtio pci config (PCI config領域)で行なわれる
  • [guest] vballoonが起床する
    • wake_up()で起こされる
    • ドライバがその要求に応えballooningを実行する
    • その結果をvirtio pci configでhostに返す
    • vballoonはhostからのackを待つ(wait_for_completion())
  • [host] guestの結果をみてホストカーネルに反映させる
    • madvise(MADV_WILLNEED or MADV_DONTNEED)を使う
    • 完了をguestに知らせる
  • [guest] その通知を受け取ったらvballoonを起床させる(complete())
    • vballoonは再びvirtio pciのconfigの変化を待ち眠る(wait_event_interruptible())