igb_uio是DPDK专为Intel以太网设备设计的UIO内核模块,通过解绑内核驱动、映射BAR寄存器、传递中断至用户空间,实现绕过内核网络栈的高性能旁路处理,但缺乏IOMMU保护,仅适用于开发或无IOMMU环境。

DPDK不能“完全接管”物理网卡驱动——它接管的是设备控制权,而非替代内核驱动本身;真正做这件事的,是 igb_uio 或 vfio-pci 这类内核模块,它们把网卡从内核网络栈手里“抢过来”,让 DPDK 应用程序直接轮询、DMA、读写寄存器。你不需要重写驱动,但必须确保硬件兼容、内核模块加载正确、绑定无冲突。
确认网卡是否支持 DPDK 并查清当前驱动
不支持的网卡强行绑定只会失败或静默丢包。先看硬件型号和当前绑定驱动:
- 运行
lspci -nn | grep -i ethernet,记下目标网卡的 PCI 地址(如0000:02:05.0)和芯片型号(如82599ES、X710、I210) - 用
ethtool -i <iface></iface>(如ethtool -i ens37)确认当前驱动名,常见有e1000、igb、ixgbe、i40e、ice - 对照 DPDK 官方支持列表:
http://core.dpdk.org/supported/,确认该驱动名 + 芯片组合是否在“Linux”栏中标为 supported - 注意:某些新网卡(如 E810)只支持
vfio-pci,不支持igb_uio;旧网卡(如 82574)可能仅支持igb_uio
加载并绑定 vfio-pci 或 igb_uio(选哪个?)
vfio-pci 是当前推荐方案,尤其在较新内核(≥4.18)、启用 IOMMU 的场景下更安全;igb_uio 更轻量,但需手动配置 UIO 框架且不支持热插拔和部分虚拟化特性。别混用。
- 启用 IOMMU(仅
vfio-pci必须):
编辑/etc/default/grub,在GRUB_CMDLINE_LINUX中追加:intel_iommu=on iommu=pt(Intel)或amd_iommu=on(AMD),然后update-grub && reboot - 加载模块:
对vfio-pci:运行modprobe vfio-pci;
对igb_uio:先编译(cd dpdk-kmods/linux/igb_uio && make),再insmod igb_uio.ko - 验证模块加载:
lsmod | grep -E "(vfio|uio)"应看到vfio_pci或igb_uio在线 - 关键:不要提前执行
modprobe加载原驱动(如ixgbe),否则后续绑定会因设备 busy 失败
用 dpdk-devbind.py 绑定网卡到用户态驱动
这是最易出错的一步。绑定前务必 down 掉网卡,且不能有进程(如 NetworkManager、systemd-networkd)正在管理它。
- 先 down 网卡:
ip link set <iface> down</iface>(如ip link set ens37 down) - 检查当前绑定状态:
dpdk-devbind.py -s,确认目标设备显示为 “Active” 且驱动列为ixgbe等原驱动 - 执行绑定(以 PCI 地址为准,不是接口名):
→ 绑vfio-pci:dpdk-devbind.py --bind=vfio-pci 0000:02:05.0
→ 绑igb_uio:dpdk-devbind.py --bind=igb_uio 0000:02:05.0 - 再次
dpdk-devbind.py -s,确认该设备 now 显示 “Active” 且驱动列为vfio-pci或igb_uio,且无 “Failed” 字样 - 常见报错:
Cannot bind to driver vfio-pci, error: -16→ 通常因 IOMMU 未启用或设备正被原驱动占用;Device is already bound to a driver→ 先用dpdk-devbind.py -u 0000:02:05.0解绑再试
DPDK 应用启动前必须做的三件事
绑定成功 ≠ 可用。DPDK 应用启动失败往往卡在这几步,而非驱动本身。
- 大页内存预分配:
echo 1024 > /proc/sys/vm/nr_hugepages(建议 1G 大页更稳,需提前挂载hugetlbfs) - CPU 隔离(可选但强烈建议):在 grub 命令行加
isolcpus=2,3,避免调度干扰轮询线程 - 确认
rte_eal_init()参数中-w 0000:02:05.0正确指定 PCI 地址;若用--vdev模拟设备则无需绑定物理网卡 - 特别注意:绑定后
ifconfig或ip link就再也看不到该网卡了——这不是故障,是预期行为。所有收发必须通过 DPDK 的rte_eth_rx_burst()/rte_eth_tx_burst()完成
最容易被忽略的是 IOMMU 启用状态与大页内存分配时机:前者决定 vfio-pci 能否加载,后者决定 DPDK 初始化时 rte_eal_init() 是否直接返回 -1。这两步没做,后面所有命令都会看似成功实则无效。



















