SRIOV直通失败,核心原因集中在IOMMU未正确开启、BIOS虚拟化选项未启用、设备驱动与内核版本不匹配、VF数量配置超限四个方面,按顺序逐项排查,绝大多数问题都能解决。本文围绕虚拟机安装sriov时物理设备直通失败的具体场景,给出从硬件层到系统层的完整排查路径与操作命令,覆盖Intel和AMD主流平台,并附带常见虚拟机平台注意事项。
为什么第一步必须检查IOMMU和BIOS虚拟化选项
SRIOV直通依赖硬件层的IOMMU(Intel VT-d或AMD IOMMU)将物理设备直接映射给虚拟机。如果BIOS中未开启VT-d或SVM,操作系统根本看不到PCIe设备的SRIOV能力,直通自然失败。 这一步的遗漏在首次配置的服务器上出现概率极高。
BIOS层面的开启路径和验证方法
重启服务器进入BIOS设置界面,路径通常为:Advanced → Intel(R) VT for Directed I/O → Enable,AMD平台对应Advanced → SVM Mode → Enable,部分服务器厂商(如Dell PowerEdge、HPE ProLiant)还会提供SR-IOV Global Enable开关,如Dell R740在System BIOS → Integrated Devices中需要将SR-IOV Global Enable设为Enabled,同时确保Virtualization Technology也是Enabled。
验证是否生效的方法简单直接:进入Linux系统后执行以下命令查看内核是否加载了对应驱动:
dmesg | grep -i -e DMAR -e IOMMU
如果输出中包含“DMAR: IOMMU enabled”或类似字段,说明IOMMU已在BIOS层开启,另一个常用验证命令是:
find /sys/kernel/iommu_groups/ -maxdepth 1 -type d | wc -l
得到的数字大于0,则IOMMU组存在,若返回0或命令不存在,说明IOMMU没有正常工作,先回BIOS重新检查。
内核启动参数中的IOMMU开启方式
BIOS开启后,还需要在操作系统内核启动参数中显式开启IOMMU支持。这一步在虚拟机安装sriov时物理设备直通失败的排查中占比很高。 对于Intel平台,需要添加intel_iommu=on;AMD平台则需添加amd_iommu=on。
编辑/etc/default/grub文件,找到GRUB_CMDLINE_LINUX行,在引号内追加参数:
GRUB_CMDLINE_LINUX="... intel_iommu=on iommu=pt"
iommu=pt表示直通模式,可以减小IOMMU对非直通设备的性能影响,保存后执行update-grub(Debian/Ubuntu)或grub2-mkconfig -o /boot/grub2/grub.cfg(CentOS/RHEL),然后重启,重启后再次执行dmesg | grep DMAR,必须能看到IOMMU成功初始化的日志,否则问题仍在硬件或BIOS层。
设备自身状态排查:SRIOV能力是否被正确识别
IOMMU开启后,需要确认PCIe设备本身的SRIOV能力是否被系统正确识别,多数情况下,物理设备直通失败是因为设备在主机侧就没有正确暴露VF(Virtual Function)接口。
检查网卡型号和当前驱动状态
以最常见的Intel X710/XL710网卡为例,先确认硬件识别正常:
lspci | grep -i ethernet
正常应看到类似Ethernet controller: Intel Corporation Ethernet Controller X710 for 10GbE SFP+的输出,再查看当前使用的驱动:
lspci -k -s 03:00.0 | grep -i "kernel driver"
如果驱动是i40e,说明加载了原生SRIOV驱动,如果是igb或ixgbe等非原生驱动,需要先卸载并加载正确驱动。行业共识认为,驱动选择错误是导致SRIOV直通失败的一个隐蔽原因。
查看VF数量是否已成功生成
SRIOV的核心在于从PF(Physical Function)上创建VF,通过以下命令查看当前设备支持的VF数量上限:
cat /sys/bus/pci/devices/0000:03:00.0/sriov_totalvfs
创建VF的操作方式有两种,运行时创建(重启后配置会消失):
echo 4 > /sys/bus/pci/devices/0000:03:00.0/sriov_numvfs
永久生效则需修改模块配置文件,对于i40e驱动,在/etc/modprobe.d/i40e.conf中写入:
options i40e max_vfs=4
同时需要确保系统加载驱动时启用了IOMMU,这里有一个容易踩的坑点:如果PCIe设备在IOMMU组内与其他设备绑定在同一组,直通时会因IOMMU组隔离限制而失败。 查看方法:
readlink /sys/bus/pci/devices/0000:03:00.0/iommu_group
如果同组内有多个设备,直通时必须将整组设备都分配给虚拟机,或者使用vfio-pci驱动接管整组设备。
用VFIO驱动接管物理设备
SRIOV直通推荐使用VFIO驱动。启用VFIO驱动是虚拟机安装sriov时物理设备直通失败解决方案中的关键动作。 将设备绑定到VFIO前,需要先解绑原有驱动:
modprobe vfio-pci echo 0000:03:00.0 > /sys/bus/pci/devices/0000:03:00.0/driver/unbind echo 0000:03:10.0 > /sys/bus/pci/drivers/vfio-pci/bind
更优雅的方式是通过内核参数直接指定设备ID,编辑/etc/default/grub的GRUB_CMDLINE_LINUX行添加:
vfio-pci.ids=8086:1572,8086:1575
其中8086:1572是PF的设备ID,8086:1575是VF的设备ID,重启后执行lspci -nnk确认设备已绑定到vfio-pci驱动。
虚拟机平台上SRIOV直通的实际配置差异
不同虚拟化平台对SRIOV直通的配置方式差异较大,失败时排查方向也不一样,以下按KVM/QEMU、VMware、Proxmox VE三个常见平台分别说明。
KVM/QEMU平台:通过libvirt配置直通
在KVM环境中,使用virsh编辑虚拟机配置,添加hostdev设备段:
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0000' bus='0x03' slot='0x10' function='0x0'/>
</source>
</hostdev>
这里的slot='0x10'对应VF的PCI地址,配置完成后执行virsh define /etc/libvirt/qemu/your-vm.xml重新定义虚拟机。
如果虚拟机启动时报错“Device has no available resources”,说明VF已经被其他虚拟机占用,或者VF数量配置超过设备上限。排查时先执行ip link show查看VF状态,确认哪些VF已被其他虚拟机使用。
VMware vSphere平台:直通需要硬件直通模式
vSphere平台对SRIOV直通的要求相对特殊,需要先在vCenter中开启直通功能:
- 进入主机配置 → PCI设备 → 选择VF对应的设备 → 勾选“启用SRIOV”
- 在虚拟机编辑界面 → 添加PCI设备 → 选择对应的VF
此时ESXi需要识别设备为SRIOV设备,如果看不到SRIOV选项,常见原因是主机未开启VT-d,在vSphere的排查中,多数情况下需要先确认ESXi的直通配置文件中包含设备ID,SSH登录ESXi后执行:
esxcli hardware pci pcipassthru list
该命令会列出所有支持直通的设备,如果设备未出现在列表中,说明硬件不被ESXi支持,或者BIOS设置不完整。
Proxmox VE平台:Web界面操作与底层验证
Proxmox VE(PVE)的SRIOV配置相对友好,但失败原因与KVM类似,在PVE的Web管理界面中,选择虚拟机 → 硬件 → 添加 → PCI设备,选择SRIOV的VF设备。
如果报错找不到设备,先在PVE宿主机上确认VF已成功创建:
echo 4 > /sys/class/net/enp3s0f0/device/sriov_numvfs
然后使用ip link show查看VF是否生成,PVE的常见问题是默认内核未开启iommu=pt参数,需要编辑/etc/default/grub后执行update-grub,操作与原生Linux保持一致。
从日志中精准定位直通失败的根本原因
当以上步骤都确认无误但直通仍然失败时,日志是最后的可靠依据。系统日志中记载了直通失败的直接原因,比盲目重新编译内核有效得多。
内核日志与dmesg排查重点
执行dmesg | tail -100查看最近的报错,重点检索三个关键词:
vfio-pci:确认VFIO是否成功接管设备DMAR或IOMMU:确认IOMMU是否正常工作SR-IOV或VF:确认SRIOV能力是否初始化
典型错误ERROR: Device is already in use by another driver出现时,说明设备尚未解绑原有驱动。先解决驱动冲突,再验证直通,这个顺序不能颠倒。
libvirt日志中记录的设备访问冲突
KVM环境下,/var/log/libvirt/qemu/目录下对应虚拟机名的日志文件会记录更详细的错误,Failed to bind device to vfio-pci: Device or resource busy”提示设备仍被占用。
另一个高价值排查点在于确认设备中断是否由vfio正确分配:
cat /proc/interrupts | grep vfio
如果看到vfio相关中断号,说明设备中断已成功映射,若中断信息缺失,则需要检查vfio-iommu-type1模块是否加载:
lsmod | grep vfio
输出应包含vfio_iommu_type1、vfio_pci、vfio_virqfd三个模块,缺少时手动加载:
modprobe vfio_iommu_type1
常见故障场景与修复对照表
以下整理了实际运维中遇到频率较高的直通失败场景,可直接对照定位。
| 故障现象 | 根本原因 | 修复命令或操作 |
|---|---|---|
| 虚拟机启动报“No IOMMU detected” | BIOS未开启VT-d | BIOS中开启VT-d后重启 |
| 创建VF时报“Resource temporarily unavailable” | sriov_numvfs写入值超过设备上限 | cat /sys/bus/pci/devices/0000:03:00.0/sriov_totalvfs查看上限后重新设置 |
| 直通后虚拟机内网卡不识别 | 虚拟机操作系统缺少SRIOV网卡驱动 | 到网卡厂商官网下载对应驱动,或切换到Windows Server版本 |
| 虚拟机无法启动,提示设备被占用 | VF已被其他虚拟机使用 | 在宿主机上执行ip link show确认占用情况,停用占用VM |
| 直通成功但吞吐量远低于预期 | iommu未启用pt模式 | 添加内核参数iommu=pt后重启 |
直通失败还有一个被忽略的场景:涉及物理设备直通失败的价格成本问题,对于采用SRIOV方案构建研发测试环境的团队,建议优先使用支持SRIOV的中低端网卡(如Intel X520-DA2),这类设备在电商平台的价格区间大概在200-800元,定位为测试用途性价比更高,生产环境则优先选用服务器厂商认证过的网卡型号,避免因固件兼容性问题导致临时换卡。
关于物理设备直通失败的三个常见问题
SRIOV直通失败后,能否退回到传统的PCI直通方案?
可以,如果VF创建或分配始终不成功,可以直接将PF设备整体直通给虚拟机,此时虚拟机独占整个物理网卡。但这种方式失去了SRIOV将一个物理设备切成多个虚拟设备的核心优势,且会影响宿主机的网络连接(如果该网卡是管理口的话),建议在SRIOV配置彻底无法解决时,再考虑退回PCI直通,同时调整虚拟机的网络拓扑。
Windows虚拟机内看不到SRIOV网卡的原因是什么?
Windows虚拟机内看不到直通网卡,多数原因是Windows系统未能识别设备的PCIe配置空间,一半情况下,需要在Windows设备管理器中将“网络适配器”中存在感叹号的未知设备手动更新驱动,驱动路径需指向网卡厂商提供的Windows版SRIOV驱动,另一个常见原因与宿主机有关:创建VF时使用了max_vfs参数但未设置num_vfs,Windows无法获得有效的VF配置信息,在宿主机上确认/sys/class/net/eth0/device/sriov_numvfs的值为非零即可排除该问题。
SRIOV直通后虚拟机迁移会不会失败?
会,这与SRIOV直通的设计机制直接相关,直通设备绑定在特定宿主机的物理PCI总线上,即使vMotion功能开启,也无法将带有SRIOV直通设备的虚拟机热迁移到另一台主机,如果业务需求涉及虚拟机跨物理机迁移,建议评估改用OVS+DPDK方案,或使用带有SRIOV支持的分布式虚拟交换机配合进行冷迁移,需要说明的是,SRIOV直通带来的性能提升通常远高于虚拟交换机损耗,因此原厂专业服务(即专家服务方案)更多侧重于这类环境下的运维规划。
归结到最后,SRIOV直通失败在绝大多数情况下不是陌生概念,而是常见配置链路中的一环缺失,从BIOS的VT-d开关,到内核的IOMMU参数,再到VF数量的准确分配,每层都验证一遍,配合dmesg日志定位,物理设备直通失败的问题就能以最高效率解决。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/614612.html





