为了实现多个虚拟机能够共享同一个物理设备的资源,并且达到设备直接分配的性能,PCI-SIG 组织发布了 SR-IOV 规范,该规范定义个了一个标准化的机制,用以原生地支持实现多个共享的设备,目前 SR-IOV最广泛的应用是在以太网卡设备的虚拟化方面
要使 SR-IOV 设备分配正常工作,必须在主机 BIOS 和内核中启用 IOMMU 功能,然后重新启动系统
# Intel
~]# grubby --args="intel_iommu=on iommu=pt" --update-kernel=ALL
# AMD
~]# grubby --args="iommu=pt" --update-kernel=ALL
1、SR-IOV 中引入的两个新功能类型
-
Physical Function(PF,物理功能):PF就是一个普通的 PCI-e 设备(带有SR-IOV功能),可以放在宿主机中配置和管理其他 VF,它本身也可以作为一个完整独立的功能使用
-
Virtual Function(VF,虚拟功能):由 PF 衍生而来的“轻量级”的 PCI-e 功能,包含数据传送所必需的资源,但是仅谨慎地拥有最小化的配置资源。VF 通过 PF 的配置之后,可以分配到客户机中作为独立功能使用
一个具有 SR-IOV 功能的设备能够被配置为在 PCI 配置空间中呈现出多个 Function(包括一个PF和多个VF),每个 VF 都有自己独立的配置空间和完整的基址寄存器。Hypervisor 通过将 VF 实际的配置空间映射到客户机看到的配置空间的方式,实现将一个或多个 VF 分配给一个客户机
在 KVM 中,可以将一个或多个 VF 分配给一个客户机,客户机通过自身的 VF 驱动程序直接操作设备的VF而不需要 Hypervisor 的参与
2、查看SR-IOV支持
在宿主机 Linux 环境中,可以通过 lspci -s $BDF -v
的命令来查看网卡 PCI 信息的 Capabilities 项目,以确定设备是否具备 SR-IOV 功能
[root@kvm ~]# lspci -s 07:00.0 -v
07:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
Subsystem: Intel Corporation Ethernet Server Adapter I350-T2
Flags: bus master, fast devsel, latency 0, IRQ 16, NUMA node 0, IOMMU group 47
Memory at fb200000 (32-bit, non-prefetchable) [size=1M]
Memory at fb384000 (32-bit, non-prefetchable) [size=16K]
Expansion ROM at fb300000 [disabled] [size=512K]
Capabilities: [40] Power Management version 3
Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+
Capabilities: [70] MSI-X: Enable+ Count=10 Masked-
Capabilities: [a0] Express Endpoint, MSI 00
Capabilities: [100] Advanced Error Reporting
Capabilities: [140] Device Serial Number 00-e0-c0-ff-ff-4f-04-28
Capabilities: [150] Alternative Routing-ID Interpretation (ARI)
# 此处说明该网卡支持SR-IOV
Capabilities: [160] Single Root I/O Virtualization (SR-IOV)
Capabilities: [1a0] Transaction Processing Hints
Capabilities: [1c0] Latency Tolerance Reporting
Capabilities: [1d0] Access Control Services
Kernel driver in use: igb
Kernel modules: igb
通过 sysfs 中开放出来的设备的信息,我们可以知道具体某款网卡设备到底支持多少VF(sriov_totalvfs),以及当前有多少 VF(sriov_numvfs)
# 支持VF的总数量
[root@kvm ~]# cat /sys/bus/pci/devices/0000\:07\:00.0/sriov_totalvfs
8
# 已分配VF的数量
[root@kvm ~]# cat /sys/bus/pci/devices/0000\:07\:00.0/sriov_numvfs
0
3、使用PF衍生VF
-
通过 sysfs 动态生成及增减(推荐)
# 衍生出5个VF [root@kvm ~]# echo 5 > /sys/bus/pci/devices/0000\:07\:00.0/sriov_numvfs [root@kvm ~]# cat /sys/bus/pci/devices/0000\:03\:00.3/sriov_numvfs 5 # 查看看PF和VF的所属关系 [root@kvm ~]# ls -l /sys/bus/pci/devices/0000\:07\:00.0/virtfn* lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn0 -> ../0000:08:10.0 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn1 -> ../0000:08:10.4 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn2 -> ../0000:08:11.0 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn3 -> ../0000:08:11.4 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn4 -> ../0000:08:12.0 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn5 -> ../0000:08:12.4 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn6 -> ../0000:08:13.0
如果在使用该方法创建 VF 时,出现以下错误,就需要使用第二种方法衍生 VF
[root@kvm ~]# echo 1 > /sys/bus/pci/devices/0000\:07\:00.0/sriov_numvfs bash: echo: 写错误: 没有那个文件或目录 [root@kvm ~]# dmesg igb 0000:07:00.0: driver does not support SR-IOV configuration via sysfs
-
通过 PF 驱动(如 igb,ixgbe)加载时候指定 max_vfs 参数
这种方法不推荐使用,因为操作的时候,如果设备是通过该网卡连接网络的,会导致网络中断
[root@kvm ~]# modprobe -r igb; modprobe igb max_vfs=7 [root@kvm ~]# lspci | grep -i eth 06:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 1b) 07:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) 07:00.1 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) 08:10.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:10.4 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:11.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:11.4 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:12.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:12.4 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:13.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01)
可以通过在 modprobe.d 路径中创建相应驱动的启动配置文件,让系统加载驱动时候自动带 max_vfs 参数
[root@kvm ~]# vim /etc/modprobe.d/igb.conf options igb max_vfs=7
由于 VF 是共享和使用对应 PF 上的部分资源,因此要使 SR-IOV 的 VF 能够在客户机中工作,必须保证其对应的 PF 在宿主机中处于正常工作状态
4、查看PF与VF相关信息
-
查看PF和VF的所属关系
[root@kvm ~]# ls -l /sys/bus/pci/devices/0000\:07\:00.0/virtfn* lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn0 -> ../0000:08:10.0 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn1 -> ../0000:08:10.4 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn2 -> ../0000:08:11.0 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn3 -> ../0000:08:11.4 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn4 -> ../0000:08:12.0 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn5 -> ../0000:08:12.4 lrwxrwxrwx 1 root root 0 5月 2 21:30 /sys/bus/pci/devices/0000:07:00.0/virtfn6 -> ../0000:08:13.0
-
查看虚拟网卡(VF)信息
[root@kvm ~]# lspci -s 08:10.0 -v 08:10.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) ...... Kernel driver in use: igbvf Kernel modules: igbvf
5、SR-IOV优缺点
-
优势
- 真正实现了设备的共享
- 接近于原生系统的高性能
- 相比于 VT-d,SR-IOV 可以用更少的设备支持更多的客户机,可以提高数据中心的空间利用率
-
不足
- 对设备有依赖,只有部分 PCI-E 设备支持 SR-IOV
- 使用 SR-IOV 时,不方便动态迁移客户机
6、SR-IOV使用示例
-
PF衍生VF
[root@kvm ~]# lspci | grep -i eth 07:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) 07:00.1 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) # 衍生4个VF [root@kvm ~]# modprobe -r igb; modprobe igb max_vfs=4 [root@kvm ~]# lspci | grep -i eth 07:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) 07:00.1 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) 08:10.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:10.4 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:11.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) 08:11.4 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) # 查看从PF\VF属关系 [root@kvm ~]# ls -l /sys/bus/pci/devices/0000\:07\:00.0/virtfn* lrwxrwxrwx 1 root root 0 5月 2 21:50 /sys/bus/pci/devices/0000:07:00.0/virtfn0 -> ../0000:08:10.0 lrwxrwxrwx 1 root root 0 5月 2 21:50 /sys/bus/pci/devices/0000:07:00.0/virtfn1 -> ../0000:08:10.4 lrwxrwxrwx 1 root root 0 5月 2 21:50 /sys/bus/pci/devices/0000:07:00.0/virtfn2 -> ../0000:08:11.0 lrwxrwxrwx 1 root root 0 5月 2 21:50 /sys/bus/pci/devices/0000:07:00.0/virtfn3 -> ../0000:08:11.4
-
将其中一个VF隐藏,供客户机使用
[root@kvm ~]# lspci -Dn -s 08:10.0 0000:08:10.0 0200: 8086:1520 (rev 01) [root@kvm ~]# echo 0000:08:10.0 > /sys/bus/pci/drivers/igbvf/unbind [root@kvm ~]# echo -n "8086 1520" > /sys/bus/pci/drivers/vfio-pci/new_id [root@kvm ~]# lspci -s 08:10.0 -k 08:10.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) Subsystem: Intel Corporation Device 00a2 Kernel driver in use: vfio-pci Kernel modules: igbvf
如果提示:bash: /sys/bus/pci/drivers/vfio-pci/new_id: 没有那个文件或目录,需要加载 vfio-pci 模块
[root@kvm ~]# modprobe vfio-pci
-
分配VF给客户机
可以通过 virt-manager 添加该 PCI 设备,也可以使用 CLI 的方式添加,此处介绍使用 CLI 将其添加到客户机中
[root@kvm ~]# virsh attach-interface rocky9-minimal hostdev 0000:08:10.0 --managed --live --config 成功附加接口
-
客户机中查看信息
[root@vm-rocky9 ~]# lspci | grep -i eth 01:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01) 07:00.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) [root@vm-rocky9 ~]# lspci -Dn -s 07:00.0 0000:07:00.0 0200: 8086:1520 (rev 01) [root@vm-rocky9 ~]# lspci -s 07:00.0 -v 07:00.0 Ethernet controller: Intel Corporation I350 Ethernet Controller Virtual Function (rev 01) ...... Kernel driver in use: igbvf Kernel modules: igbvf