网卡虚拟化简介
网卡虚拟化的目的是将一张物理的网卡虚拟出多个可以单独使用的虚拟网卡。物理网卡只有一张,网线只有一根,所以网卡的虚拟化和CPU虚拟化类似,通过分时复用实现,在数据收上来后将数据分流到不同的虚拟网卡上实现虚拟化。所以网卡虚拟化本质是数据分类分流。
- 纯软件虚拟化
需要一个虚拟网卡管理器,数据到达后网卡,虚拟网卡管理器将其分类分流交给不同的虚拟网卡,比如通过mac、vlan等分类。如qemu中模拟网卡、Virtio等。 - 硬件辅助虚拟化
纯软件的虚拟化方法虚拟化效果好但是效率低下,所以出现硬件辅助将在软件分流等虚拟化功能卸载到网卡中。如SR-IOV(Single Root I/O Virtualization)等
SR-IOV
SR-IOV(Single Root I/O Virtualization)是PCIe设备虚拟化技术规范。如果网卡实现了SR-IOV规范,当网卡通过PCIe总线接入系统时,系统可以通过PCIe总线扫描出多个虚拟网卡设备,每个虚拟网卡设备具有独立的 PCIe Configuration Space(配置空间)、 PCIe BDF、 MSI-X 中断、 MAC 地址和 Rx/Tx Queues等
具体规范可见https://composter.com.ua/documents/sr-iov1_1_20Jan10_cb.pdf
PS:规范快速下载链接 https://pan.baidu.com/s/1kUrho2M7hRJeCNXSxwLN8A?pwd=7zkx
提取码:7zkx
在SR-IOV规范中,定义了设备可以支持两个类别的功能:PF(Physical Function)和VF(Virtual Function)。
PF顾名思义就是普通物理设备原有的全部功能,同时PF拥有了配置和初始化VF的能力。SR-IOV规范中要求PF增加了一个SR-IOV专用的寄存器,用于配置和开关SR-IOV能力。
VF是PF的功能阉割版,具备物理设备的部分功能,PF下多个VF共享PF资源,VF也是PCIE总线上的一个物理设备,只是和物理设备共用一个PCIE slot。
VF和PF支持是不一样的所以设备驱动通常会做分开,比如网卡设备驱动通常会分别实现VF和PF驱动。以intel的10GE网卡82599为例,PF的驱动是标准的ixgbe,VF的驱动是ixgbevf。
根据规范,单个PF最多可以生成65536个VF。网卡支持的具体VF数量与网卡的硬件资源有关,例如82599支持64个VF。
Virtio
纯软件虚拟化中入qemu模拟设备场景,由qemu实现IO设备的模拟,guest OS不用做任何修改即可运行在qemu上。但IO操作会涉及到特权指令执行等,guest OS是运行在用户态,没有权限执行特权指令,当运行到特权指令时会触发CPU异常发生VM-eixt,由qemu捕获异常,之后模拟指令执行再VM-enty,出现频繁切换,影响性能。另外数据传输时通常会先拷贝到qemu后再拷贝到guest OS上,拷贝路径为:host内核<->host用户态(qume)<->guest的kernel<->guest用户态,存在多次拷贝性能降低。
模拟设备的好处是guest完全感知不到自己是虚拟机,使用原生驱动,坏处是多次拷贝内存、频繁陷入qemu导致上下文切换等性能损耗严重。
Virtio是将guest OS的驱动做修改,qemu根据Virtio协议模拟出一个虚拟设备,guest OS通过virtio驱动操作virtio虚拟设备,不用访问限制的资源,使用当前权限执行数据的传输,同时也通过共享内存等手段减少数据的拷贝。
在Virtio协议中,驱动侧称为前端。设备模拟侧称为后端。前端和后端的数据传输已经可以避免频繁VM-eixt和VM-entry。但从物理设备到qemu模拟的virtio虚拟设备任是不高效的。qemu实现后端设备的模拟,数据到达后端之前会先达到内核然后再到qemu,再到guest,任存在多次上下文切换。所以通过将后端实现卸载到kernel中可以减少很多上下文切换等,比如通知机制可以直接由内核态触发eventfd而不是内核态先通知qemu再由qemu触发eventfd通知guest。