3. 使用VFIO驱动替代UIO
任务目标
将Intel 82599网卡从内核驱动igb_uio切换为vfio-pci驱动,验证IOMMU组隔离与设备访问权限配置正确,使DPDK应用能够通过VFIO通道接管网卡。
环境依赖
- Linux内核 ≥ 3.6(支持VFIO),建议4.18+
- CPU与主板支持IOMMU(Intel VT-d / AMD-Vi)
- DPDK已编译(含
vfio-pci内核模块,通常随内核发布) - 系统已安装
dpdk-devbind.py脚本(位于DPDK源码usertools/目录)
实现步骤与关键代码
1. 启用IOMMU并加载VFIO模块
在/etc/default/grub的GRUB_CMDLINE_LINUX中添加intel_iommu=on iommu=pt(AMD平台使用amd_iommu=on),执行update-grub后重启。确认IOMMU已启用:
dmesg | grep -i -e DMAR -e IOMMU
加载VFIO相关模块:
modprobe vfio
modprobe vfio-pci
2. 检查网卡当前驱动与IOMMU组
# 查看网卡PCI地址(以0000:02:00.0为例)
lspci -nn | grep -i ethernet
# 查看当前绑定的驱动
readlink /sys/bus/pci/devices/0000:02:00.0/driver
# 查看IOMMU组编号(关键验证点)
ls /sys/kernel/iommu_groups/
cat /sys/bus/pci/devices/0000:02:00.0/iommu_group/type
预期输出:iommu_group目录存在且编号非空,type文件内容为DMA。若iommu_group目录不存在,说明IOMMU未正确启用。
3. 解绑旧驱动并绑定VFIO
# 解绑当前驱动(假设为igb_uio)
echo "0000:02:00.0" > /sys/bus/pci/drivers/igb_uio/unbind
# 绑定vfio-pci
echo "vfio-pci" > /sys/bus/pci/devices/0000:02:00.0/driver_override
echo "0000:02:00.0" > /sys/bus/pci/drivers/vfio-pci/bind
# 验证绑定结果
readlink /sys/bus/pci/devices/0000:02:00.0/driver
预期输出:.../vfio-pci。若绑定失败,检查dmesg中是否有Device is in use或IOMMU group is not viable错误。
4. 验证IOMMU组隔离与权限
# 查看IOMMU组内设备列表(应只包含该网卡)
ls /sys/kernel/iommu_groups/<组编号>/devices/
# 检查VFIO设备节点权限
ls -l /dev/vfio/
cat /sys/bus/pci/devices/0000:02:00.0/iommu_group/type
判定标准:
/dev/vfio/<组编号>存在且属主为root:root,权限为rw-------(或rw-rw----若已配置udev规则)- IOMMU组内设备列表仅包含目标网卡,无其他功能设备(如同一物理端口的另一个网卡)
- 若组内包含多个设备,需全部解绑并绑定到
vfio-pci,否则VFIO无法工作
5. 使用DPDK绑定脚本验证(推荐方式)
# 使用DPDK官方脚本完成上述操作(更安全)
./usertools/dpdk-devbind.py --bind=vfio-pci 0000:02:00.0
# 查看绑定状态
./usertools/dpdk-devbind.py --status-dev net
预期输出中该网卡驱动显示为vfio-pci。此脚本会自动处理解绑、驱动覆盖和绑定流程,并检查IOMMU组可用性。
运行验证
使用DPDK自带的dpdk-testpmd验证VFIO通道可用:
./build/app/dpdk-testpmd -l 0-1 -n 4 -- -i
若VFIO配置正确,testpmd启动时不会报EAL: Detected UIO driver或VFIO group is not viable错误,并显示EAL: VFIO support initialized。进入交互界面后执行show port summary all,若端口状态为UP且无错误,则验证通过。
常见问题
- IOMMU组不可用:组内存在其他未解绑设备,需将所有设备绑定到
vfio-pci或使用ACS补丁(不推荐生产环境)。 - 权限拒绝:运行DPDK应用的用户需加入
vfio组,或通过chmod 666 /dev/vfio/<组编号>临时授权(仅测试用)。 - 内核不支持:确认内核配置
CONFIG_VFIO_IOMMU_TYPE1与CONFIG_VFIO_PCI为y或m。