2010年12月22日水曜日

FreeBSD用virtioドライバ ステータスアップデート (2010/12/21)

10月頃に作成したFreeBSD用virtioドライバですが、その後もボチボチと作業を続けております。

これまで開発した範囲では性能問題なども一通り解決しているので、
もうすこしコードを整理して、 -STABLE 品質として必要な機能を追加したら
ドライバをメーリングリストなどに投稿したいと思っています。

各ドライバのステータスなどについて紹介します。



■ 機能ドライバのステータス


  • virtio-net


    • vCPU = 1, 2の場合に e1000 エミュレーションよりスループットが高くなるよう改善

    • シャドウページテーブル環境下におけるパフォーマンス悪化を改善

    • メモリ管理方式の変更(malloc→bus_dmaによる連続したGuest-Physicalメモリ空間の確保)

    • OSにより確保されるmbufへの直接データ受信、バッファの再利用による高速化

    • 途中: Merged RX Buffers

    • 未: Hardware Checksum Offload

    • 未: GSO

    • 未: TSO

    • 未: Promiscous mode support, MAC Address filtering, Tagged VLAN Support

    • 未: MSI-X support

    • 未: Driver Media Status/Statics support

  • virtio-blk (新たに実装)


    • vCPU = 1, 2 の場合に SCSI Emulation よりも高性能、かつ CPU 負荷が低下するよう実装

      ※ qemu-kvm + FreeBSD は相性が悪いらしく、これだけでは性能は不十分

    • 済: VIRTIO_BLK_T オペレーション (ディスクへの単純読み書き)

    • 済: FLUSH オペレーション

    • 未: SCSI Device Passthrough

その他 Memory Balloon, Console は未着手

テープデバイス/dev/rmt/Xのデバイス番号をリセットする

Solaris 環境でテープデバイスを認識させる場合、基本的には /dev/rmt/0 から 1, 2, 3, ... と順番に番号が振られます。

しかし、機器移設時にテープドライブの接続先ポートを間違えたり、テープドライバの個体 ID が変わったりすると、「それまではとは違うテープドライブ」と認識され、意図せず /dev/rmt/1, /dev/rmt/2, ... とデバイス番号が進んでしまう場合があります。

このような場合には、まず /dev/rmt/ 以下にあるデバイスファイルを削除した後にテープドライブを接続して再起動すると、 Solaris 起動時にドライバ?がテープのデバイスファイルを適切に作成しなおしてくれます。



# cd /dev/rmt
# rm 0*                     ※チキンなので * ではなく 0* などとしました:p
# rm 1*
# shutdown -y -g0 -i6

システム起動時のテープドライブがどのデバイス名で認識されているかは cfgadm -al コマンドにて確認できます。

2010年12月5日日曜日

FreeBSD + KVMの環境でちょっと過ごしてみてわかってきたノウハウ(1)

最近 FreeBSD 用の virtio ドライバに割と情熱を注いでいるのですが(そろそろ公開したい!)、
ドライバの性能が出ないという状況になって調査したときに多少ノウハウが得られたのでメモがてら掲載しておきます。

まずの一つ目のネタ。kvm_statコマンド。

kvm statistics

 efer_reload                  0       0
 exits                401230913    2152
 fpu_reload               52997       0
 halt_exits           133189538     757
 halt_wakeup            5259576      15
 host_state_reload    170030018     977
 hypercalls                   0       0
 insn_emulation       252392427    1359
 insn_emulation_fail          0       0
 invlpg                 2684292       0
 io_exits               4130425      17
 irq_exits              8935347      39
 irq_injections         3195682       0
 irq_window                   0       0
 largepages                   0       0
 mmio_exits            28482276     179
 mmu_cache_miss          698023       0
 mmu_flooded              40079       0
 mmu_pde_zapped          216076       0
 mmu_pte_updated         180285       0
 mmu_pte_write          1931218       0
 mmu_recycled                 0       0
 mmu_shadow_zapped       696204       0
 mmu_unsync                 877       0
 nmi_injections               0       0
 nmi_window                   0       0
 pf_fixed               4719781       0
 pf_guest                817765       0
 remote_tlb_flush        234452       0
 request_irq                  0       0
 signal_exits                 0       0
 tlb_flush              4903428       0

性能が出ていない場合には非常に参考になる内容です。ソースコードなどを見て何をしてくれているのか調査したわけではないのですが・・・





exits
発生したVMEXITすべての回数を示します。VMEXITとはIntel VT/AMD-VのCPU仮想化支援技術においてVMを実行し、何らかの理由(I/Oとかメモリ管理で何かがおきてVMMの介入が必要になったとか、タイムスライスを使い切ったとか色々)によりゲストを停止させた回数になります。仮想化支援技術があったとしてもVMMモード/ゲストモードの切り替えは非常にコストの高いものなので、これをいかに削減するかがポイントになります。



insn_emulation
それまでに発生したハードウェアエミュレーションの回数?を示しているようですが、細かいことは未調査。

io_exits

I/Oポートに対するアクセスで発生したVMEXITの回数を示します。
この値が大きくなる場合はハードウェアへのI/Oが頻発しており
性能劣化につながっていることが予想されます。
このような操作は全てVMEXITを引き起こしますので、いかにI/Oポートアクセスなどを少ない回数で済まさせるかが、VMの実質実効時間をのばすためにVMEXIT回数を削減するという観点で気になる数字です。

irq_exits

VMの実行中、物理ハードウェアにからの割り込みによってVMEXITした回数を示しているようです。この数字が大きい場合は物理ハードウェア側のIRQ割り込みをいかに減らすかの検討が必要になりそうです……。

irq_injections

ハードウェアエミュレータ(qemu-kvm)がVMに対して発行した割り込みの回数を示します。
IRQを使用している場合、IRQが発生すると、IRQをシェアするデバイスドライバ群が
ISR(Interrupt Status Register)をポーリングします。
このため割り込み回数×IRQ・・・と、共有するデバイス数が多いほどVMEXITの発生回数も増加にも繋がることから、ドライバを作るのであればこれをいかに低く抑えるかがポイントになります。

mmio_exits

メモリマップドI/OのためのVMEXIT回数です。

mmu_pte_write

シャドウページテーブル利用時、VM内のページテーブルのエントリ(Page Table Entry)を更新した数を示すようです。この値は、たとえばゲストOS上でmalloc()やfree()を行った場合にも実装次第で発生します。値が大きい場合は仮想マシン上のメモリ管理機構について再検討する余地があると言えます。この値はEPT/NPTが利用できないハードウェアでシャドウページテーブルによる負荷を見るのに利用できます。ここはゲスト内のプログラムのメモリ管理を工夫することで削減が可能です。ドライバなどであれば普段利用中にゼロから動かさせない、ぐらい高い目標を持ってもよいでしょう。