Skip to content

virtioとvhostの違い

ゲストOSが準仮想化デバイスにアクセスするときのインターフェイスを定めたAPI仕様。

virtio インターフェイスを実装したデバイスはいくつかある。

  • virtio-net
  • virtio-blk
  • virtio-scsi
  • virtiofs

Linuxカーネルでは vqueuevring を使ってデータを管理する。この実現にはQEMU, KVM, libvirtが関係している。

仮想化を支援するカーネルの機能。メモリ管理やリソース管理の機構が実装されている。

KVMと一緒に利用する場合はデバイスのエミュレーション部分を担当する。ゲストOSを立ち上げるごとにQEMUプロセスが生成される。

これはXMLで記述した設定ファイルをQEMUのコマンドラインオプションに展開するためのツールで、プログラミング言語のライブラリではなかった。なので利用しなくても動作に支障はない。

vhostvirtio の一部を実装したプロトコル。デバイスごとにフロントエンドとバックエンドが定義される。

全てをQEMUプロセスで実装すると、データの入出力があるたびにコンテキストスイッチやユーザー/カーネル空間の切り替えが発生して非常に効率が悪い。なので効率的な実装にオフロードするためのプロトコルとして定義される。

例えばネットワークの場合、vhost を使う場合でも使わない場合でもゲストOSからみたフロントエンドは virtio-net から変わらず、ゲストOSのカーネル空間でコントロールプレーンの処理(フロントエンド)を担当する。しかし vhost を使わないときは virtio-net がゲストからみたバックエンドとなるが、これはQEMUに実装されているのでバックエンドがパケットを処理する際に vmexit 等でオーバーヘッドが発生して都合が悪い。そのため、vhost-net バックエンドではホストOSのカーネル空間でデータプレーンの処理(バックエンド)を担当する。結局フロントエンドが動作する場所はQEMUプロセスなので、ホストOSからみるとユーザー空間なのだが、VMEXIT 等でコンテキストスイッチが起きないような実装になっているらしい。これはRed Hatの図が分かりやすい。

vhost-net の他には以下のようなバックエンドがある。

バックエンド実装説明
vhost-netカーネル空間ネットワークのデータ転送を行う
vhost-user-net1ユーザー空間ネットワークのデータ転送を行う
vhost-blkカーネル空間ブロックデバイスのIO処理を行う
vhost-user-blkユーザー空間ブロックデバイスのIO処理を行う
vhost-mouse-pciカーネル空間
vhost-user-inputユーザー空間

コンテキストスイッチの有無でいえばユーザー空間で実装する意味があるのかと思うが、DPDKやSPDKでは全てをユーザー空間で処理するので、そういう用途なのだろう。

ユーザープロセスに処理をオフロードするための、QEMUとユーザープロセス間で扱うプロトコル。vhost のフロントエンドはQEMUが担当し、バックエンドは別のユーザープロセスが対応する。

以下のドキュメントでバックエンドのリストが掲載されている。

  1. 歴史的な理由なのか分からないが古いドキュメントではvhost-userと表記されている場合もある