virtio勉強会 #1 「virtioの基本的なところ(DRAFT版)」

5,504 views
5,280 views

Published on

virtio勉強会 #1でしゃべった内容。

未完成版。pdfで上げたのが見えないので上げ直し。

Published in: Technology

virtio勉強会 #1 「virtioの基本的なところ(DRAFT版)」

  1. 1. 12013/06/09virtio の基本的なところ (DRAFT)@n_kane
  2. 2. 2参考資料✤ というかこのスライドよりむしろ以下の資料を読みましょう ...✤ Virtio PCI Card Specification✤ http://github.com/rustyrussell/virtio-spec✤ とある virtio ドライバの接続部分〜インタフェース〜 by @hasegaw✤ http://www.slideshare.net/TakeshiHasegawa1/osc2011-tokyofall-virtio
  3. 3. 3ここでするお話について✤ virtio の基本的なところのお話✤ どううごいているか✤ どうシステムソフトウェアから使えるか✤ ( つまり )virtio pci card specification のサブセット的な内容✤ 主に plan9 の virtio 実装をメインにお話を進めます
  4. 4. 4ここでしないお話について✤ 仮想化周りの歴史的背景、実現方法、実装、構造 e.t.c.✤ virtio での通信が VMM 内でどうハンドリングされているか✤ indirect モード , MSI-X の活用など
  5. 5. 5お題目✤ virtio で何ができるの?✤ virtio デバイスとその見え方✤ virtio を使った通信
  6. 6. 6virtio で何ができるの?
  7. 7. 7virtio でホスト・ゲスト間通信!✤ 何か不思議な力により✤ ホスト&ゲスト OS 間で共有できるリングバッファができます✤ しかもメモリ空間が許すかぎり何本でも✤ ここに適切に情報を詰めてやることで✤ ゲストからホストへ、あるいはホストからゲストへデータの転送ができます
  8. 8. 8データの転送ができるなら ....✤ 準仮想化ドライバ作るときに使えるよね!✤ たとえば✤ コントロール用 , TX 用 , RX 用のリングバッファがあれば✤ NIC っぽい動作をさせられるのでは! ( ホスト側ががんばれば )
  9. 9. 9“virtio デバイス”というもの
  10. 10. 10virtio device✤ virtio デバイス✤ なんらかのまとまった機能を持った仮想的な対象物 = デバイス✤ たとえば NIC, ブロックデバイス , ファイルシステム e.t.c✤ いくつかのリングバッファを用いて操作してやることで一定の役割を果たしてくれる人のこと
  11. 11. 11virtio device as a PCI device✤ virtio デバイスはゲストから、 PCI デバイスとして認識されます✤ ベンダ ID : 0x1AF4✤ プロダクト ID : 0x1000 - 0x1040✤ これだとどの virtio デバイスだか区別がつかない ....✤ Subsystem Device ID でデバイスのタイプを判断
  12. 12. 12http://marsee101.blog19.fc2.com/blog-entry-84.html より拝借0x1000 〜 0x1040 0x1AF4IDID TYPETYPE1 NIC2 BLOCK3 CONSOLE5MEMORYBALLOON9 9PSubsytem Device ID の例
  13. 13. 13認識できたら初期化 ... の前に✤ PCI I/O Space に何が入っているかを抑えておきましょうデバイス ( ホスト ) からゲストに対して提示される利用可能な機能(feature) 一覧 ( 各ビット )ゲストが利用する機能 (feature) を書き込みデバイス ( ホスト ) に伝えるフィールドVirtio Header
  14. 14. 14認識できたら初期化 ... の前に✤ PCI I/O Space に何が入っているかを抑えておきましょうQselect に示される番号のリングバッファのアドレス ÷ 4096(guest physical)操作中のリングバッファの番号Qselect に示される番号のリングバッファ長 ( デスクリプタの数 )Virtio Header
  15. 15. 15認識できたら初期化 ... の前に✤ PCI I/O Space に何が入っているかを抑えておきましょうデバイスの初期化状態や利用状況についてゲストが告知するために利用割り込み状態の通知リングバッファを操作した際にゲストがその番号を書き込むVirtio Header
  16. 16. 16virtio デバイスの初期化 ( 共通 )1 各 OS ごとの PCI デバイス認識フェーズ2 ベースアドレスレジスタから map( 左の構造がみえるようになる )3 Status の ACKNOWLEDGE(0x1) ビットを立ててデバイスを発見できたこと、 virtio デバイスだと分かっていることを通知Virtio Header16
  17. 17. 17virtio デバイスの初期化 ( 共通 )4 Status の DRIVER(0x2) ビットを立てて、ゲストがこのデバイスをサポート ==ドライバを実装していることを通知5 デバイス固有の初期化6 リングバッファの用意 ( 後述 )7 Devfeat の内、利用する物を Drvfeat に書き込み ( 後述 )Virtio Header17
  18. 18. 18virtio デバイスの初期化 ( 共通 )8 すべて正常に成功したら , Status のDRIVER_OK(0x4) ビットを立てる8 失敗したら , Status の FAILED(0x80)ビットを立てる以上で attach の部分は終了!18
  19. 19. 19リングバッファの構造
  20. 20. 20リングバッファとは✤ 実態はメモリ上のこんなかんじのデータ
  21. 21. 21リングバッファとは✤ 実態はメモリ上のこんなかんじのデータデスクリプタテーブルavailable リングused リング
  22. 22. 22デスクリプタ✤ 一つの転送を扱うエンティティ
  23. 23. 23デスクリプタ✤ 一つの転送を扱うエンティティ転送対象のデータのアドレス(guest physical)データ長このデスクリプタの扱いについてのフラグ後続して転送するデスクリプタの番号
  24. 24. 24デスクリプタ✤ 一つの転送を扱うエンティティフラグフラグ (( 値値 )) 意味意味VRING_DESC_F_NEXT(0x01)next フィールドに示される後続要素がある ( デスクリプタチェーンによる転送 )VRING_DESC_F_WRITE(0x02)このデスクリプタは ( ホストから見て )Write Only である. ホスト→ゲスト方向の転送VRING_DESC_F_INDIRECT(0x04)Indirect モードによる転送
  25. 25. 25デスクリプタテーブル✤ ( そのまま ) デスクリプタの配列✤ 長さは Virtio Header の Qsize( 個 )✤ 転送の度に動的に alloc するのではなく、このテーブルからフリーなデスクリプタを見つけてきて使うという方式✤ 基本的には”インデックス値”でアクセスされる
  26. 26. 26available リングこのリング用のフラグ( 割り込み抑制など※ ) デスクリプタテーブルused リングavail リング中の先頭インデックス値 (availidx)デスクリプタ番号を書き込むリング本体ここに指定された番号のデスクリプタが処理されるまでは割り込み抑制
  27. 27. 27used リングこのリング用のフラグ( 割り込み抑制など※ ) デスクリプタテーブルavailable リングused リング中の先頭インデックス値 (usedidx)デスクリプタ番号が書き込まれるリング本体ここに指定された番号のデスクリプタが処理されるまでは割り込み抑制
  28. 28. 28available リングと used リング✤ 基本的には前述のデスクリプタの番号を入れておく配列 ( 長さ Qsize)✤ available リング✤ ゲストがデスクリプタの番号を書き込んでリング上のインデックス値 (availidx) を進めると、それが ( ホストにより ) 処理される✤ used リング✤ ホストにより処理されたデスクリプタの番号が書き込まれ、リング上のインデックス値(usedidx) が更新される✤ 正確には”デスクリプタの番号”と”デスクリプタチェーンの長さ”が入る✤ このオペレーション周りは後述
  29. 29. 29リングバッファの扱い方 - 初期化 -
  30. 30. 30先ほど飛ばしたお話✤ リングバッファを用意するのはゲストの責任。以下の流れで行う。1 . 触りたいリングの番号 (i) を Qselect にセット2. Qsize をみる3. 0 ならこのデバイスで Qselect 番目のリングは使えないので終わり4. > 0 ならその長さのリングが使える5. 前述のリングバッファを Qsize を元に作る6. Qaddr にリングバッファの物理アドレスをセット7. i++; goto 1;Virtio Header
  31. 31. 31初期化周りの細い話✤ virtio の本筋とはあまり関係ないけれど、利便性のために OS でやっていること✤ デスクリプタテーブルのチェーン化 ( 右図 )✤ フリーなデスクリプタ番号の保持 ( 右図の free)✤ avail リング , used リングの先頭アドレス保持✤ 過去の usedidx の保持 (lastused)
  32. 32. 32リングバッファの扱い方 - 転送 -
  33. 33. 33転送の手順✤ 箇条書きにすると ....1 . 転送パスのキューを引っ張ってくる2. その中でフリーなデスクリプタを探してきて、適切に情報を詰める3. avail リングの先頭にその番号を書き込み , availidx を +1 して更新4. Virtio Header の Qnotify に転送パスのキューの番号を書き込む✤ この時点でホストに制御が移って処理が行われる
  34. 34. 34分かりづらいので図に ...初期状態4 番がフリーなので情報をつめて ...availidx のところに番号を書き込むavailidx を進めて、変更を加えたリング番号を Qnotify に書き込み
  35. 35. 35転送が終わったら ....✤ 割り込みが入って何かデバイス ( ホスト ) から応答があるはず ....→used リングを見よう1 . 現在の usedidx と lastused の差から変更があったことを検知2. lastused == usedidx になるまで used リングのデスクリプタを処理3. 処理が終わったデスクリプタはデスクリプタテーブルに戻す
  36. 36. 36イメージ図割り込みが入った時点usedidx と lastused の差から変更を検知一つ進めて該当するデスクリプタを処理終わった物は返す
  37. 37. 37slide is never done
  38. 38. 38virtio-net の場合の事情✤ virtqueue は3つ : tx/rx/control✤ Drvfeat

×