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。