Virtioについてのまとめ


# Virtio

- 仮想環境におけるI/Oフレームワーク
- virtio_netはvirtio上に構築されたネットワーク用の準仮想化デバイスドライバ

![スクリーンショット 2016-07-16 16.00.35.png](https://qiita-image-store.s3.amazonaws.com/0/13615/6b276267-7b78-7b4b-56fa-dda0cc2f4b9a.png "スクリーンショット 2016-07-16 16.00.35.png")

(図は[KVM PV DEVICES](http://www.linux-kvm.org/images/d/dd/KvmForum2007%24kvm_pv_drv.pdf)より引用)

# Virtioのアーキテクチャ

- 準仮想化デバイスドライバは共通のvirtioと呼ばれる仮想キューのインタフェースを使用して構築される
- 仮想キューはゲストとホストOS間で共有されるメモリ上に構築されるリングキューとして実装される
- ハイパーバイザー側にも各フロンエンドデバイスに対応するバックエンドデバイスドライバーが存在

![virtio フレームワークのアーキテクチャー概要](https://www.ibm.com/developerworks/jp/linux/library/l-virtio/figure3.gif)

(図は[virtio: Linux の I/O 仮想化フレームワーク](https://www.ibm.com/developerworks/jp/linux/library/l-virtio/)のvirtio フレームワークのアーキテクチャー概要より引用)

# Virtioのバックエンド実装

1. virtual queueへの通知及びデータアクセスをQEMU上で行う 
2. host側のカーネル空間からデータのアクセスを行う 
3. host上のユーザ空間のプロセスが直接ゲストOSとデータの送受信を行う 

([virtio guest side implementation: PCI, virtio device, virtio net and virtqueue](https://jipanyang.wordpress.com/2014/10/27/virtio-guest-side-implementation-pci-virtio-device-virtio-net-and-virtqueue/))

ネットワークの実装で言えば1.がvirtio_net, 2がvhost_netに該当する

# パケット処理の流れ(virtio_net)

![スクリーンショット 2016-07-17 0.06.44.png](https://qiita-image-store.s3.amazonaws.com/0/13615/af6d7a1b-79b2-9eb0-a265-d96684f9d691.png "スクリーンショット 2016-07-17 0.06.44.png")

(図は[Network I/O Virtualization - Advanced Computer Networks](http://www.systems.ethz.ch/sites/default/files/file/COURSES/2014_SPRING_COURSES/2014_Spring_Adv_Comp_Net/12-VirtualMachines.pdf)より引用)


# パケット処理の流れ(vhost_net)

![スクリーンショット 2016-07-17 0.09.21.png](https://qiita-image-store.s3.amazonaws.com/0/13615/451b2127-56de-2ecc-a1e5-66d03bd51510.png "スクリーンショット 2016-07-17 0.09.21.png")

(図は[Network I/O Virtualization - Advanced Computer Networks](http://www.systems.ethz.ch/sites/default/files/file/COURSES/2014_SPRING_COURSES/2014_Spring_Adv_Comp_Net/12-VirtualMachines.pdf)より引用)

- パケット送信時はvhostのworker threadがvirtqueueから読み取りtap経由でパケットを送信する
- パケット受信はvhostのworker threadがtapをpollingし、tapからデータを読み取りvirtqueueへデータをキューイングする
- QEMUのユーザ空間を介さずにguest osとhostのカーネル空間でパケットの送受信が可能なため、パケット送受信時に余計なコンテキストスイッチが走らない

([QEMU Internals: vhost architecture](http://blog.vmsplice.net/2011/09/qemu-internals-vhost-architecture.html))

# Multi-queue virtio-net

- パケットの送受信処理をゲストOSのvcpuの数にスケールさせるための技術
- ハードウェアに依存しない仕組み

![仮想環境においてパケットの送受信の仕組み](http://www.linux-kvm.org/images/e/e3/Ver1.jpg)

(図は[Multiqueue virtio-net](http://www.linux-kvm.org/page/Multiqueue)より引用)


# 参考資料

[virtio: Linux の I/O 仮想化フレームワーク](https://www.ibm.com/developerworks/jp/linux/library/l-virtio/)

- virtioの概要を把握するのに丁度いいドキュメント

[ハイパーバイザの作り方](http://syuu1228.github.io/howto_implement_hypervisor/)

- FreeBSDのハイパーバイザを題材にハイパーバイザーの実装方法を説明している

[virtio introduction](http://www.slideshare.net/zenixls2/052-virtio-introduction-17191942)

- virtioを使ったfrontendとbackendの通信に関しての資料

[qemu virtio backend](https://github.com/qemu/qemu/blob/791b7d2340cfafcac9af7864343cf23504d57804/hw/net/virtio-net.c)

- virtio-netのソース

[qemu virtio source code](https://github.com/qemu/qemu/blob/791b7d2340cfafcac9af7864343cf23504d57804/hw/virtio/virtio.c)

- virtioのソース

[極める！ KVM](https://www.nic.ad.jp/ja/materials/iw/2012/proceedings/d1/d1-Asama.pdf)

- 仮想環境のパケットの送受信(vhostについても)に発生する処理が図で分かりやすく記載されている

[Hardware Accelerated VirtIO Networking for NFV](http://events.linuxfoundation.org/sites/events/files/slides/Hardware%20Accelerated%20Virtio%20networking%20for%20NFV_linuxCon.pdf)

- vhostのパケット送受信の流れが関数レベルで詳細に書かれている

[Kernel-based Virtual Machine Technology](http://www.fujitsu.com/global/documents/about/resources/publications/fstj/archives/vol47-3/paper18.pdf)

- qemuとkvmがどう連携しているか簡潔に書かれている