本文介绍
virtio-net和vhost-net网路实现原理。其中,vhost-net是运行在宿主机内核空间的后端,virtio-net是运行在虚拟机内核空间的前端。
virtio-net 架构图
virtio-net 一套网络半虚拟化驱动 + 设备的方案。

说明:
控制通道(control path)用来管理前端(Front-end)和后端(Back-end)数据通道和参数配置,如图中蓝实线所示数据通道(data path)传输数据,如图中Host User Space中红实线所示vring虚拟机中与物理机共享的内存通知通道(notifications)传递 vmexit/vCPU irq 等,如图中红虚线所示virtio data path interfaceQemu 和宿主机内核tap通信
网络通信流程
- 虚拟机中
virtio-net driver通过虚拟PCIE 总线连接到QEMU模拟的virtio-net device;驱动初始化后,两者建立控制通道(control path),协商通信能力,虚拟机分配vring并与QEMU共享 网络发包:虚拟机更新vring,通过KVM通知QEMU,QEMU在将报文发送到宿主机内核的TAP设备网络收包:QEMU收到报文,填充vring,通过KVM向虚拟机触发虚拟中断,虚拟机完成收包
问题
- 上下文切换多,报文和通知需要在
虚拟机、KVM、QEMU和宿主机内核四者之间多次切换 - 依赖
QEMU传递数据,效率比较低
vhost-net/virtio-net 架构
vhost 是 virtio 的一种后端实现方案(一般实现在用户态的QEMU中,但 vhost 实现在宿主机内核中 vhost-net.ko),vhost 通过将 virtio 的数据通道卸载到 内核态(如vhost-net) 或 用户态 来实现性能的提升

说明:
virtio-net driver作为前端,运行在虚拟机内核态vhost-net作为后端,运行在宿主机内核态virtio 控制平面(control plane)将vring协商好后,数据脱离QEMU,被卸载到vhost-net,仅负责控制层面的事情vhost会启动内核线程,负责处理虚拟机的数据。其中,虚拟机的vring直接映射到宿主机内核态,比较高效- 与
virtio-net相比,vhost-net处理数据在内核态,在发送到tap的时候少了一次数据的拷贝
vhost 与 kvm 的事件通信通过 eventfd 机制来实现,主要包括两个方向的 event:
- 一个是
guest到vhost方向的kick event,通过ioeventfd实现 - 另一个是
vhost到guest方向的call event,通过irqfd实现
配置
QEMU 2.10.0 和 libvirt 3.7.0后,可以配置 tx_queue_size 和 rx_queue_size