38
1 2013/06/09 virtio のののののののの (DRAFT) @n_kane

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

Embed Size (px)

DESCRIPTION

virtio勉強会 #1でしゃべった内容。 未完成版。pdfで上げたのが見えないので上げ直し。

Citation preview

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

1

2013/06/09

virtio の基本的なところ(DRAFT)@n_kane

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

2

参考資料

✤ というかこのスライドよりむしろ以下の資料を読みましょう ...

✤ Virtio PCI Card Specification

✤ http://github.com/rustyrussell/virtio-spec

✤ とある virtio ドライバの接続部分〜インタフェース〜 by @hasegaw

✤ http://www.slideshare.net/TakeshiHasegawa1/osc2011-tokyofall-virtio

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

3

ここでするお話について

✤ virtio の基本的なところのお話

✤ どううごいているか

✤ どうシステムソフトウェアから使えるか

✤ ( つまり )virtio pci card specification のサブセット的な内容

✤ 主に plan9 の virtio 実装をメインにお話を進めます

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

4

ここでしないお話について

✤ 仮想化周りの歴史的背景、実現方法、実装、構造 e.t.c.

✤ virtio での通信が VMM 内でどうハンドリングされているか

✤ indirect モード , MSI-X の活用など

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

5

お題目

✤ virtio で何ができるの?

✤ virtio デバイスとその見え方

✤ virtio を使った通信

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

6

virtio で何ができるの?

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

7

virtio でホスト・ゲスト間通信!

✤ 何か不思議な力により

✤ ホスト&ゲスト OS 間で共有できるリングバッファができます

✤ しかもメモリ空間が許すかぎり何本でも

✤ ここに適切に情報を詰めてやることで

✤ ゲストからホストへ、あるいはホストからゲストへデータの転送ができます

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

8

データの転送ができるなら ....

✤ 準仮想化ドライバ作るときに使えるよね!

✤ たとえば

✤ コントロール用 , TX 用 , RX 用のリングバッファがあれば

✤ NIC っぽい動作をさせられるのでは! ( ホスト側ががんばれば )

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

9

“virtio デバイス”というもの

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

10

virtio device

✤ virtio デバイス

✤ なんらかのまとまった機能を持った仮想的な対象物 = デバイス

✤ たとえば NIC, ブロックデバイス , ファイルシステム e.t.c

✤ いくつかのリングバッファを用いて操作してやることで一定の役割を果たしてくれる人のこと

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

11

virtio device as a PCI device

✤ virtio デバイスはゲストから、 PCI デバイスとして認識されます

✤ ベンダ ID : 0x1AF4

✤ プロダクト ID : 0x1000 - 0x1040

✤ これだとどの virtio デバイスだか区別がつかない ....

✤ Subsystem Device ID でデバイスのタイプを判断

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

12

http://marsee101.blog19.fc2.com/blog-entry-84.html より拝借

0x1000 〜 0x1040 0x1AF4

IDID TYPETYPE

1 NIC

2 BLOCK

3 CONSOLE

5MEMORYBALLOON

9 9P

Subsytem Device ID の例

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

13

認識できたら初期化 ... の前に

✤ PCI I/O Space に何が入っているかを抑えておきましょう

デバイス ( ホスト ) からゲストに対して提示される利用可能な機能(feature) 一覧 ( 各ビット )

ゲストが利用する機能 (feature)を書き込みデバイス ( ホスト ) に伝えるフィールド

Virtio Header

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

14

認識できたら初期化 ... の前に

✤ PCI I/O Space に何が入っているかを抑えておきましょう

Qselect に示される番号のリングバッファのアドレス ÷ 4096(guest physical)

操作中のリングバッファの番号

Qselect に示される番号のリングバッファ長 ( デスクリプタの数 )

Virtio Header

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

15

認識できたら初期化 ... の前に

✤ PCI I/O Space に何が入っているかを抑えておきましょう

デバイスの初期化状態や利用状況についてゲストが告知するために利用

割り込み状態の通知

リングバッファを操作した際にゲストがその番号を書き込む

Virtio Header

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

16

virtio デバイスの初期化 ( 共通 )

1 各 OS ごとの PCI デバイス認識フェーズ

2 ベースアドレスレジスタから map( 左の構造がみえるようになる )

3 Status の ACKNOWLEDGE(0x1) ビットを立ててデバイスを発見できたこと、 virtio デバイスだと分かっていることを通知

Virtio Header

16

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

17

virtio デバイスの初期化 ( 共通 )

4 Status の DRIVER(0x2) ビットを立てて、ゲストがこのデバイスをサポート == ドライバを実装していることを通知

5 デバイス固有の初期化

6 リングバッファの用意 ( 後述 )

7 Devfeat の内、利用する物を Drvfeatに書き込み ( 後述 )

Virtio Header

17

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

18

virtio デバイスの初期化 ( 共通 )

8 すべて正常に成功したら , Status のDRIVER_OK(0x4) ビットを立てる

8 失敗したら , Status のFAILED(0x80)ビットを立てる

以上で attach の部分は終了!18

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

19

リングバッファの構造

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

20

リングバッファとは

✤ 実態はメモリ上のこんなかんじのデータ

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

21

リングバッファとは

✤ 実態はメモリ上のこんなかんじのデータ

デスクリプタテーブル

available リング

used リング

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

22

デスクリプタ

✤ 一つの転送を扱うエンティティ

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

23

デスクリプタ

✤ 一つの転送を扱うエンティティ

転送対象のデータのアドレス(guest physical)

データ長

このデスクリプタの扱いについてのフラグ

後続して転送するデスクリプタの番号

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

24

デスクリプタ

✤ 一つの転送を扱うエンティティ

フラグフラグ (( 値値 )) 意味意味

VRING_DESC_F_NEXT(0x01)

next フィールドに示される後続要素がある ( デスクリプ

タチェーンによる転送 )

VRING_DESC_F_WRITE(0x02)

このデスクリプタは ( ホストから見て )Write Only である . ホスト→ゲスト方向の転

VRING_DESC_F_INDIRECT

(0x04)Indirect モードによる転送

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

25

デスクリプタテーブル

✤ ( そのまま ) デスクリプタの配列

✤ 長さは Virtio Header の Qsize( 個 )

✤ 転送の度に動的に alloc するのではなく、このテーブルからフリーなデスクリプタを見つけてきて使うという方式

✤ 基本的には”インデックス値”でアクセスされる

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

26

available リング

このリング用のフラグ( 割り込み抑制など※ ) デスクリプタテーブル

used リング

avail リング中の先頭インデックス値 (availidx)

デスクリプタ番号を書き込むリング本体

ここに指定された番号のデスクリプタが処理されるまでは割り込み

抑制

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

27

used リング

このリング用のフラグ( 割り込み抑制など※ ) デスクリプタテーブル

available リング

used リング中の先頭インデックス値 (usedidx)

デスクリプタ番号が書き込まれるリング本体

ここに指定された番号のデスクリプタが処理されるまでは割り込み

抑制

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

28

available リングと used リング

✤ 基本的には前述のデスクリプタの番号を入れておく配列 ( 長さ Qsize)

✤ available リング

✤ ゲストがデスクリプタの番号を書き込んでリング上のインデックス値 (availidx) を進めると、それが ( ホストにより ) 処理される

✤ used リング

✤ ホストにより処理されたデスクリプタの番号が書き込まれ、リング上のインデックス値(usedidx) が更新される

✤ 正確には”デスクリプタの番号”と”デスクリプタチェーンの長さ”が入る

✤ このオペレーション周りは後述

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

29

リングバッファの扱い方 - 初期化 -

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

30

先ほど飛ばしたお話

✤ リングバッファを用意するのはゲストの責任。以下の流れで行う。

1. 触りたいリングの番号 (i) を Qselect にセット

2. Qsize をみる

3. 0 ならこのデバイスで Qselect 番目のリングは使えないので終わり

4. > 0 ならその長さのリングが使える

5. 前述のリングバッファを Qsize を元に作る

6. Qaddr にリングバッファの物理アドレスをセット

7. i++; goto 1;

Virtio Header

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

31

初期化周りの細い話

✤ virtio の本筋とはあまり関係ないけれど、利便性のために OS でやっていること

✤ デスクリプタテーブルのチェーン化 (右図 )

✤ フリーなデスクリプタ番号の保持 (右図の free)

✤ avail リング , used リングの先頭アドレス保持

✤ 過去の usedidx の保持 (lastused)

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

32

リングバッファの扱い方 - 転送 -

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

33

転送の手順

✤ 箇条書きにすると ....

1. 転送パスのキューを引っ張ってくる

2. その中でフリーなデスクリプタを探してきて、適切に情報を詰める

3. avail リングの先頭にその番号を書き込み , availidx を +1 して更新

4. Virtio Header の Qnotify に転送パスのキューの番号を書き込む

✤ この時点でホストに制御が移って処理が行われる

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

34

分かりづらいので図に ...

初期状態

4 番がフリーなので情報をつめて ...

availidx のところに番号を書き込む

availidx を進めて、変更を加えたリング番号を Qnotify に書き込み

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

35

転送が終わったら ....

✤ 割り込みが入って何かデバイス ( ホスト ) から応答があるはず ....→used リリリリリリリ

1. 現在の usedidx と lastused の差から変更があったことを検知

2. lastused == usedidx になるまで used リングのデスクリプタを処理

3. 処理が終わったデスクリプタはデスクリプタテーブルに戻す

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

36

イメージ図

割り込みが入った時点

usedidx と lastused の差から変更を検知

一つ進めて該当するデスクリプタを処理

終わった物は返す

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

37

slide is never done

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

38

virtio-net の場合の事情

✤ virtqueue は3つ : tx/rx/control

✤ Drvfeat