如果你搞过云计算、NFV,或者只是在自己的服务器上折腾过KVM虚拟化,大概率见过这个词——SR-IOV。网上讲它的文章不少,但多数要么浮在概念层,只告诉你“这玩意儿能让虚拟机的网络性能逼近物理机”,要么直接甩一篇驱动编译教程,跑偏了重点。这篇我想换个写法,从一张被打爆的网卡说起,把SR-IOV到底是什么、什么时候该用它、怎么一步步落地,以及那些文档里不会写的坑,一次聊透。
SR-IOV的全称是 Single Root I/O Virtualization,单根I/O虚拟化,由PCI-SIG组织定义。它解决的核心问题,是传统软件虚拟化网络在性能、延迟和CPU占用这三者之间永远无法兼得的三角困局。拿KVM最常用的virtio-net来说,流量要经过虚拟机内核、QEMU用户态、宿主机内核的vhost后端,中间隔着多次内存拷贝和上下文切换。哪怕做了vhost-user、vDPA这类优化,软件处理路径的天花板依然肉眼可见。而SR-IOV的思路很直接:既然网卡本身是硬件,为什么不能让虚拟机直接操作网卡的硬件资源?这就是它存在的意义,也是这篇所有讨论的起点。
1. 先从一张被打爆的网卡说起:SR-IOV到底解决什么问题
1.1 传统虚拟化路径的瓶颈在哪
我在早期做云平台的时候,遇到过一个特别典型的案例。一台物理机上跑了十几台虚拟机,业务量一上来,宿主机的CPU先顶不住了,光软中断就能吃掉六七个核。用perf一眼看下去,大部分时间都耗在net_rx_action和vhost_work上,整台宿主机就是一台“高级转发器”,真正用来跑业务的CPU所剩无几。更麻烦的是延迟抖动,业务高峰期p99延迟动不动翻倍,因为流量在宿主机内核排队、在QEMU进程里排队,任何一环出现竞争,波动就会直接传导到虚拟机内部。
问题的本质在于,virtio这套方案让物理网卡的中断和DMA先落到宿主机,再由宿主机软件模拟出一块 virtio-net 设备给虚拟机用。这等于把网卡的一半工作用软件重做了一遍。CPU参与得越多,性能就越差,延迟就越不稳。
1.2 PCI直通和SR-IOV的取舍
有人会问:那直接把整块物理网卡直通给一台虚拟机不就行了?这就是PCI Passthrough。性能确实好,但代价也很明显——一块物理网卡只能给一台虚拟机用,一台机器上插不了几块卡,扩展性基本为零。更别提热迁移基本别想,灵活性大打折扣。
SR-IOV恰好站在两者中间:它从一块物理网卡上,通过硬件虚拟化出多个轻量级的虚拟设备——VF(Virtual Function),每个VF都拥有独立的PCIe配置空间、独立的DMA队列、独立的中断资源。虚拟机拿到VF后,等于直接握住了一块“物理网卡的切片”,数据从网卡到虚拟机的路径完全是硬件直通,不需要宿主机CPU在中途插手。于是,一张物理网卡可以被切成几十份,每一份都拥有接近物理机的网络性能,密度和性能兼得。
1.3 哪些场景真正需要SR-IOV
现在网上把SR-IOV吹得神乎其神,但实际来看,它适合的场景没那么宽,却非常聚焦。如果你是下面这几种情况,SR-IOV可能是你的最优解。
第一类是NFV和边缘计算场景,比如vCPE、vBRAS、防火墙、DPI这类需要高吞吐、低延迟、高PPS的网络功能虚拟化。这些业务本质上是数据面应用,对转发性能极其敏感,必须让虚拟机直接操作网卡硬件。
第二类是高频交易、实时音视频处理这类对延迟抖动有极致要求的场景。我见过不少做量化交易的朋友,为了省掉哪怕几十微秒的网络延迟,不仅上SR-IOV,还专门用DPDK把收包线程绑在特定CPU核上。
第三类是高密度虚拟化环境,宿主机上的虚拟机数量多,每台都有持续的流量压力。用virtio时,CPU被网络软件路径拖死;换成SR-IOV之后,网络路径上的CPU占用几乎可以忽略不计。
反过来,如果你的虚拟机网络流量普遍很小,或者宿主机CPU资源非常富余,那SR-IOV的优势就没那么明显了。毕竟它要占用PCIe通道和IOMMU资源,配置也复杂一些,没必要为了“用技术而用技术”。
2. 拆开看看:PF、VF与硬件分流的工作原理
2.1 PF和VF到底是个什么关系
SR-IOV里有两个核心角色:PF和VF。PF就是Physical Function,物理功能。它是网卡本身呈现出来的完整PCIe功能,拥有完整的配置空间,由网卡驱动(比如ixgbe、i40e、ice、mlx5_core)接管。系统管理员通过PF来管理整块网卡,包括做VLAN配置、链路聚合、创建VF等等。
VF是Virtual Function,虚拟功能,由PF通过硬件虚拟化衍生出来。每个VF拥有独立的PCIe配置空间子集、独立的收发队列对、DMA通道和中断线。从虚拟机的角度看,VF就是一块实实在在的网卡,它不需要知道背后还有PF存在。但VF的能力是被裁剪过的,不能做全量的物理配置,只能做队列的读写、MAC地址设置等有限操作。
打个比方说,PF相当于一栋大楼的物业中心,它能管理整栋楼的水电、门禁、消防;VF相当于大楼里的独立房间,租户拿到钥匙之后可以直接开门用电用水,但你不能让租户去改装整栋楼的结构。SR-IOV就是那个把大楼切成多个房间、并给每间房独立配了水电表的技术。
2.2 网卡内部是怎么把一份硬件拆成多份的
一块支持SR-IOV的网卡,内部本质上是一个多队列设备。以Intel XL710为例,整块卡有几万个描述符资源、几百个队列对、几十个中断向量。SR-IOV的做法,是把这些资源按VF数量分组,每组分配若干队列对、一组中断、一段DMA地址空间。当网卡收包时,硬件根据MAC地址、VLAN标签或RSS哈希值,直接把包放进对应VF的队列里,再通过该VF的中断通知对应的虚拟机。
这个过程中,宿主机CPU完全没有参与数据面。DMA直接发生在网卡和虚拟机内存之间。这样CPU的软中断几乎为零,延迟也稳定得多。
有人可能问:DMA是直接写进虚拟机内存,那虚拟机是不是就能读写任意物理内存了?这里就轮到IOMMU出场了,也就是Intel VT-d或AMD IOMMU、ARM上的SMMU。IOMMU负责把VF的DMA请求做地址翻译和权限校验,确保一个VF只能访问分配给它的那部分内存。没有IOMMU,DMA直通就是一扇敞开的安全大门。所以后面配置时,BIOS里开启VT-d不仅仅是性能问题,更是安全底线。
2.3 数据面路径的直观对比
把数据路径画出来对比,你就知道SR-IOV省在哪了。
virtio-net方案,收包路径大概是:物理网卡收到数据 → DMA到宿主机内核的ring buffer → 触发硬中断 → 软中断处理协议栈 → vhost后端处理 → 通知QEMU → 映射到虚拟机内存 → 虚拟机virtio前端收包。整整七八步,每一步都有开销、都可能出现锁竞争和延迟波动。
PCI直通方案,路径是:物理网卡收到数据 → DMA直接到虚拟机内存 → 触发中断 → 虚拟机驱动处理。路径很短,但一套硬件只能给一台虚拟机。
SR-IOV的路径和PCI直通几乎一样,但区别在于:VF是经过硬件虚拟化切分的,所以可以同时存在几十个VF,分别分配给不同的虚拟机。也就是说,你拿到的是一块物理网卡的“硬件直通切片”,路径短、开销小,且密度高。这就是SR-IOV的核心价值,没有魔法,就是让硬件资源被安全地直接分享给多个虚拟机。
3. 手把手把SR-IOV跑起来:从BIOS到虚拟机
3.1 硬件环境和内核准备
真正动手之前,先确认你的硬件支持。SR-IOV要求网卡、CPU、主板三方面同时支持。网卡方面,Intel的82599、X710/XL710、E810系列,Mellanox(现在是NVIDIA)的ConnectX-4/5/6系列,Broadcom的BCM574xx系列,这些主流数据中心网卡都支持。但很多消费级网卡(尤其是板载的)是不支持SR-IOV的,购买前一定查清楚。
CPU方面需要支持VT-d(Intel)或AMD-Vi(AMD),并且BIOS里要把IOMMU相关的选项打开。现在多数服务器主板默认开启,但有些机器藏着比较深,比如在 Advanced → PCI Subsystem Settings 或 North Bridge 配置里。开启之后,把下面这行参数加到内核启动命令行里:
intel_iommu=on iommu=ptiommu=pt的意思是让IOMMU在直通模式下工作,尽量减少对非直通设备DMA映射的干预,性能损失更小。这里有一点很多人忽略:如果不开IOMMU,VF虽然能创建出来,但分配给虚拟机时大概率直接失败,或者DA进虚拟机后根本没法正常工作。所以这个参数一定要加,加完记得更新GRUB并重启。
3.2 创建VF并验证
重启确认IOMMU生效后,第一步是确认网卡驱动已经加载。以Intel的i40e驱动为例:
modprobe i40e ip link show假设你的物理网卡叫enp3s0f0。现在创建16个VF:
echo 16 > /sys/class/net/enp3s0f0/device/sriov_numvfs写入成功后,可以用lspci查看新出现的设备:
lspci | grep -i ethernet你会看到PF之外还多了一堆设备,名字通常是Ethernet Controller Virtual Function之类的。也可以用ip命令确认:
ip link show | grep -A 5 enp3s0f0此时宿主机上可能也会自动生成enp3s0f0v0这类VF的netdev接口。这个netdev接口是给某个VF建立的软件表示,主要用来从宿主机侧配置VF的MAC地址、VLAN等属性。
这里有个关键点要提醒:某些网卡驱动在模块加载时通过参数限制VF数量上限,比如老一点的ixgbe驱动有max_vfs参数。如果你需要大量VF,可能要在modprobe时指定:
modprobe ixgbe max_vfs=323.3 把VF绑定到VFIO驱动
创建好VF之后,下一步是把其中一个VF绑到vfio-pci驱动上,这样QEMU/KVM才能安全地把它直通给虚拟机。为什么不直接用网卡原始驱动?因为原始驱动会占住VF的所有权,QEMU无法接管;同时vfio-pci会配合内核的IOMMU做DMA隔离,这是安全性的关键。
在绑定之前,先找到VF的PCI地址:
lspci | grep -i ethernet # 假设你想用 0000:03:10.0 这个VF然后确保vfio-pci模块已加载:
modprobe vfio-pci手动绑定VF的推荐做法是使用driverctl工具,比手动改sysfs稳妥得多:
driverctl set-override 0000:03:10.0 vfio-pci绑定完成后,用lspci -s 03:10.0 -k查看,应该能看到Kernel driver in use: vfio-pci字样。假如没有driverctl,手动做法是:
echo 0000:03:10.0 > /sys/bus/pci/devices/0000:03:10.0/driver/unbind echo vfio-pci > /sys/bus/pci/devices/0000:03:10.0/driver_override echo 0000:03:10.0 > /sys/bus/pci/drivers_probe手动操作时要注意顺序,先解绑后覆盖。如果VF原本没有绑定任何驱动,直接设置driver_override再probe也可以。
3.4 配置虚拟机:QEMU命令行与libvirt两种方式
VFIO绑定完成之后,就能把它给虚拟机用了。先演示QEMU命令行的方式,这种方式适合脚本化和极简环境:
qemu-system-x86_64 \ -machine accel=kvm \ -m 4096 \ -smp 4 \ -drive file=/data/ubuntu.qcow2,format=qcow2 \ -device vfio-pci,host=03:10.0关键就一行-device vfio-pci,host=03:10.0。QEMU会通过VFIO框架接管这个PCI设备,然后把它呈现给虚拟机。虚拟机启动后,里面看到的是一块支持多队列的物理网卡,驱动通常是Intel的i40e、ixgbe或Mellanox的mlx5_core。
如果你用的是libvirt,需要先在宿主机上创建VFIO设备支持,然后编辑虚拟机XML,添加如下内容:
<hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x03' slot='0x10' function='0x0'/> </source> </hostdev>这里managed='yes'的含义是让libvirt在虚拟机启动时自动把VF绑定到vfio-pci,关闭时再恢复。这是最常用的方式。如果你的宿主机上有多个NUMA节点,建议把网卡所在的PCIe槽位和虚拟机的CPU内存分配放在同一个NUMA节点上,否则跨NUMA访问会让延迟明显增加,后面会展开讲。
3.5 验证虚拟机的性能是否真的提上来了
虚拟机内启动后,先看驱动是否起来:
ethtool -i eth0如果驱动是物理网卡的native驱动,说明直通成功。接下来用iperf3打一下吞吐:
iperf3 -s # 服务端在虚拟机里 iperf3 -c <虚拟机IP> -t 30 -P 8我实测下来,SR-IOV的单流吞吐比virtio-net提升大概20%到50%,但最大的变化是CPU占用。同样跑满10G线速,virtio方案下宿主机CPU风扇狂转,SR-IOV方案下宿主机的CPU几乎纹丝不动。延迟p99也从几十上百微秒降到十几微秒级别。当然具体数字因卡而异,但趋势是一致的。
如果你用perf stat查看QEMU进程的CPU占用,会发现SR-IOV模式下QEMU的CPU占用明显下降,因为网络收发的负担全部卸载到了网卡硬件上。这就是“卸载”二字的真正含义。
4. 进阶玩法:VLAN、信任模式与DPDK的组合拳
4.1 在PF侧管理VF的MAC和VLAN
SR-IOV的优势之一,是管理员可以在宿主机侧统一管控虚拟机的网络属性,而不是丢给虚拟机自己乱搞。通过PF的netdev接口,可以直接设置每个VF的MAC地址和VLAN标签。比如:
ip link set enp3s0f0 vf 0 mac 00:11:22:33:44:55 ip link set enp3s0f0 vf 0 vlan 100设置VLAN后,网卡硬件会自动给该VF的流量打上VLAN 100的标签,同时过滤掉非该VLAN的入站流量。这个能力在云平台里非常有用:租户之间隔离VLAN,但又不用在宿主机上创建一堆Linux bridge,因为VLAN过滤和插入是网卡硬件完成的,CPU完全不参与。
在配置多张SR-IOV网卡时,要注意VF的VLAN与PF上联交换机端口的trunk配置要匹配,否则流量进不来也出不去。这就是很多新手觉得“SR-IOV太不稳定”的原因之一——其实不是SR-IOV的问题,是上联交换机的VLAN没配好。
4.2 spoofchk与trust mode:安全边界怎么设
VF毕竟是虚拟设备,如果不加限制,它就能伪造任意MAC地址去发包,这在租户网络里是绝对不能接受的。所以网卡驱动提供了Spoof Check(防欺骗检查)机制,默认开启。它保证VF只能使用管理员指定的MAC地址发送数据,不允许自定义。
管理命令是:
ip link set enp3s0f0 vf 0 spoofchk on还有一个相关概念叫trust mode。默认情况下,VF是不受信任的,它能做的事情很有限,比如不能修改自己的MAC(除非spoofchk关闭),也不能设置某些高级特性。开启trust mode后,VF获得了更多控制权:
ip link set enp3s0f0 vf 0 trust on但trust mode是一把双刃剑:开启后,VF可以设置自己的MAC地址,哪怕spoofchk开启也无法完全限制。所以在多租户环境中,强烈建议保持trust off,让云平台的控制面统一管理MAC和VLAN。这跟我做网络运维时的原则一致:安全边界宁可收紧,别贪图方便。
4.3 让SR-IOV跑DPDK:用户的真正狂欢
SR-IOV的最大威力,是跟DPDK组合使用。DPDK(Data Plane Development Kit)本质上是一套绕过内核协议栈的包处理库,直接通过PMD驱动操作网卡硬件,将收包、发包完全放在用户态。当DPDK跑在VF上时,整条数据链路是:物理网卡 → 硬件队列 → VF → 虚拟机用户态DPDK应用。内核只在启动阶段参与设备初始化,数据面完全不经过它。
要把VF给DPDK用,做法和给虚拟机直通类似,也是把VF绑定到vfio-pci驱动。在虚拟机内部,DPDK的dpdk-devbind.py脚本会接管这个VF。关键点在于,DPDK在用户态需要锁住内存(MLOCK),所以要确保:
ulimit -l unlimited以及使用大页内存:
echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages mount -t hugetlbfs pagesize=2M /dev/hugepagesDPDK的EAL参数里也需要指定Hugepage和PCI地址。比如:
./testpmd -l 0-3 -n 4 -- -i这个组合我在NFV项目里用了很久,实测吞吐可以跑到接近线速,PPS轻松达到数百万甚至千万级别,而CPU占用比内核协议栈低一个数量级。可以这么理解:SR-IOV负责把网络I/O的硬件资源切分成“管道”,DPDK负责在用户态以最直接的方式从管道里取水送水,两者配合,把软件虚拟化带来的损耗降到了最低。
4.4 ARM服务器上的SMMU与SR-IOV差异
如果你用的不是x86服务器,而是ARM服务器(比如鲲鹏、飞腾),SR-IOV的原理一样,但IOMMU换成了SMMU。内核启动参数不再是intel_iommu=on,而需要在设备树或ACPI中启用SMMU。很多ARM平台的BIOS对SR-IOV的支持没有x86那么成熟,创建VF时更容易遇到中断分配不均、SMMU性能瓶颈等问题。
实话说,在ARM平台上调SR-IOV的坑比x86多一些。建议先用官方自带的光纤卡测试,确认SMMU和中断控制器(GIC)的配合没问题,再部署到生产。这里记住一个原则:SR-IOV依赖的硬件特性非常多,平台成熟度直接决定你踩坑的深度。
5. 踩坑记录:常见问题与排查思路
5.1 VF创建不了,往往是IOMMU和驱动的锅
创建VF最常见的报错是写/sys/class/net/enp3s0f0/device/sriov_numvfs时返回Invalid argument。多数情况是IOMMU没开,或者驱动模块参数导致VF数量受限。排查路线应该固定下来:先确认内核参数里有没有intel_iommu=on,再确认BIOS里VT-d有没有开,最后看驱动版本和模块参数。
如果是Intel的卡,内核里还可以查看:
dmesg | grep -i iommu dmesg | grep -i vf如果IOMMU正常但VF还是创建不了,检查一下PCIe的ACS(Access Control Services)能力。有些PCIe交换机不支持ACS或默认关闭ACS,SR-IOV的VF间DMA隔离就会受影响,导致创建失败。这时需要在BIOS里开启ACS,或者用pcie_acs_override=downstream内核参数临时绕过。这个参数在数据中心网卡上几乎用不到,但在消费级主板上很常用。我试过不少主板,发现消费级平台对SR-IOV的支持非常分裂,有些板子连VF都创建不了,那就不建议折腾了。
5.2 虚拟机启动失败:VFIO和直通配置的典型问题
虚拟机上配置了VFIO设备后,启动时失败,常见报错有以下几种:
第一种是vfio-pci: probe of 0000:03:10.0 failed with error -22。这个通常是VFIO设备没有正确解绑原始驱动,或者IOMMU未开启。用lspci -s 03:10.0 -k确认一下是不是已经是vfio-pci。
第二种是qemu-system-x86_64: -device vfio-pci,host=03:10.0: No available IOMMU。这说明内核IOMMU没开,或者ACPI DMA Remapping表缺失。检查一下dmesg | grep DMAR有没有报错。在老一点的BIOS上,如果没开Advanced → VT-d → IOMMU Support,就会这样。
第三种是虚拟机内网卡down。这种往往是spoofchk或者VF的MAC地址没有设置好。在宿主机侧给VF设置MAC之后,虚拟机内还要确认IP配置。有时候是VF的driver没有设置多队列,导致虚拟机内只有单队列,性能上不去。用ethtool -L eth0 combined 4把队列数开上去。
5.3 性能没提升?先确认中断和NUMA
如果你做完SR-IOV发现性能没比virtio强多少,大概率不是SR-IOV的问题,而是中断处理没绑好或者内存跨NUMA了。
VF的中断是MSI-X中断,直接投递到虚拟机指定的vCPU上。但宿主机侧如果跑着irqbalance,它可能会把宿主机处理VF相关中断的CPU到处迁移,导致延迟抖动。我一般建议在SR-IOV的场景下关掉irqbalance,改用irqaffinity脚本或手工把中断绑到固定CPU上。
要知道,NUMA的坑比中断更隐蔽。VF的DMA要写进虚拟机内存,如果虚拟机内存所在的NUMA节点和网卡所在的NUMA节点不同,那么每次DMA都要跨节点访问,延迟和带宽都会受到明显影响。检测方法很简单:看虚拟机的内存属于哪个NUMA节点,再看网卡PCIe slot在哪个节点。lstopo命令可以直接显示拓扑。配置虚拟机的时候,尽量让vCPU和内存与网卡在同一NUMA节点。
OpenStack里相关参数是hw:numa_nodes和hw:numa_mempolicy=preferred,手动qemu场景就指定CPU和内存的NUMA绑定。这个细节不做的话,SR-IOV的延迟优势可能直接减半,真金白银买的硬件性能被白白浪费。
5.4 干扰与抖动:不可忽视的邻居效应
SR-IOV虽然硬件隔离了数据面,但有些资源依然是共享的,比如网卡的PCIe带宽、缓存、RQ(接收队列)等。如果一台物理机上跑了几十个使用不同VF的虚拟机,它们会争夺同一块物理网卡的PCIe总带宽。所以做容量规划时,不能只看单VF性能,也要算总带宽。
另外,网卡的LRO(Large Receive Offload)特性在虚拟化环境下可能造成大包延迟抖动。因为LRO会把多个小包聚合再提交给驱动,虽然吞吐好看,但单包延迟不稳定。如果业务对延迟敏感,建议在VF上关闭GRO/LRO:
ethtool -K eth0 lro off gro off这个和物理机上的调优一致,但在虚拟化环境下的影响更明显。毕竟,虚拟机里面的网络栈本来就多了一层抽象,硬件卸载特性叠加软件路径后,行为可能出乎意料。
5.5 一张速查表:SR-IOV常见问题与处理建议
| 现象 | 常见原因 | 排查/解决方法 |
|---|---|---|
| sriov_numvfs 写入失败 | IOMMU未开启、驱动参数限制 | 检查内核启动参数、BIOS VT-d、modprobe参数 |
| 创建VF后ip link不显示 | 驱动不支持VF或未重新加载 | 检查驱动版本,modprobe -r + modprobe |
| 虚拟机启动失败,报No available IOMMU | 未启用IOMMU或ACPI DMA表异常 | 检查dmesg DMAR,确认BIOS设置 |
| 虚拟机内网卡down | VF的MAC没设置或spoofchk限制 | 在PF侧设置VF MAC,检查spoofchk |
| 性能提升不明显 | 中断未绑定、NUMA不匹配、GRO/LRO干扰 | 关irqbalance,绑定CPU,检查NUMA拓扑 |
| 延迟抖动明显 | 邻居VF争抢带宽、LRO聚合、软中断漂移 | 限速(QoS)、关GRO/LRO、固定中断CPU |
| 跨主机通信不通 | 上联交换机VLAN配置不匹配 | 检查交换机trunk以及PF的VLAN配置 |
| VF无法绑定vfio-pci | 原始驱动未解绑、PCI地址错误 | 用driverctl override 或手动解绑再probe |
写在最后:我的几条经验之谈
SR-IOV这项技术,从PCI-SIG发布规范到今天,已经十多年了。它在高性能虚拟化网络领域的地位至今没有被撼动,不是因为名字唬人,而是它确实踩准了“硬件功能直接给虚拟化用”这个核心逻辑。但技术归技术,落地的时候踩过的坑只有自己知道。最后分享几条我个人在项目里的体会。
第一,不要为了用而用。如果你的业务对网络性能没有极致要求,virtio已经完全够用,没必要增加运维复杂度。但如果你做NFV、高频转发,或者宿主机CPU已经成了瓶颈,SR-IOV是目前性价比最高的解药之一。
第二,硬件选型极其关键。同样的SR-IOV,不同品牌、不同型号的网卡表现差异巨大。Intel和Mellanox(NVIDIA)算是踩坑最少的选择,消费级网卡除非你自己有心理准备能折腾,否则别轻易碰。
第三,SR-IOV只是整个高性能虚拟化网络链条中的一环。它与DPDK的配合、与云平台(OpenStack或Kubernetes)的集成、与上层业务模型的适配,才真正决定最终效果。建议先在一个测试节点上完整跑通,再谈规模部署,别一上来就全量铺开。
希望这篇对你有帮助。如果你也在调SR-IOV,欢迎在评论区聊聊你踩过的坑,说不定你的经验正好是别人需要的答案。