4. DPDK 环境搭建:编译DPDK、绑定网卡驱动与大页内存配置

在开始流分类硬件卸载的故障排查之前,必须搭建一个稳定、可复现的 DPDK 运行环境。本章节将详细讲解从源码编译 DPDK、绑定用户态驱动(igb_uio / vfio-pci)以及配置大页内存的完整流程。环境搭建的规范性直接决定了后续 RSS 与 FDIR 规则调试的成败。

环境前提: 确保已安装 Linux 内核开发包(kernel-devel)、GCC、make、meson、ninja、pciutils 以及 libnuma-dev。推荐使用 Ubuntu 20.04+ 或 CentOS 7.9+ 发行版。

4.1 DPDK 源码编译与安装

DPDK 从 19.11 版本开始全面采用 meson 构建系统。以下步骤以 DPDK 21.11 LTS 为例,该版本对 RSS 和 FDIR 硬件卸载支持最为成熟。

4.1.1 获取源码与配置

# 下载 DPDK 21.11 LTS
wget https://fast.dpdk.org/rel/dpdk-21.11.tar.xz
tar xf dpdk-21.11.tar.xz
cd dpdk-21.11

# 使用 meson 配置构建,指定安装路径
meson setup build --prefix=/opt/dpdk-21.11 \
  -Dexamples=all \
  -Denable_docs=false \
  -Dmachine=default \
  -Dc_args='-O2 -march=native'

4.1.2 编译与安装

# 编译
ninja -C build

# 安装到指定目录
sudo ninja -C build install

# 设置环境变量(建议写入 ~/.bashrc)
export RTE_SDK=/opt/dpdk-21.11
export RTE_TARGET=x86_64-native-linux-gcc
export PATH=$RTE_SDK/bin:$PATH
export PKG_CONFIG_PATH=$RTE_SDK/lib/x86_64-linux-gnu/pkgconfig:$PKG_CONFIG_PATH
编译验证: 执行 ldconfig -p | grep dpdk 应能看到 librte_*.so 共享库;执行 pkg-config --modversion libdpdk 应返回 21.11。

4.2 网卡驱动绑定:igb_uio 与 vfio-pci 选型

DPDK 需要将网卡从内核原生驱动(如 ixgbe、i40e、ice)解绑,并绑定到用户态驱动。两种主流驱动对比如下:

特性 igb_uio vfio-pci
依赖模块 igb_uio.ko(需单独编译) vfio-pci(内核内置,需开启 IOMMU)
IOMMU 要求 不需要 必须(intel_iommu=on / amd_iommu=on)
DMA 安全性 较低(无隔离) 高(支持 VFIO 隔离)
中断模式 传统中断 / MSI-X MSI-X + 中断重映射
推荐场景 快速原型、无 IOMMU 环境 生产环境、多进程、VF 直通

4.2.1 编译 igb_uio 内核模块

# 进入 DPDK 源码目录的 kernel/linux/igb_uio
cd $RTE_SDK/kernel/linux/igb_uio
make

# 加载模块
sudo modprobe uio
sudo insmod igb_uio.ko

# 验证加载
lsmod | grep igb_uio

4.2.2 使用 vfio-pci(推荐生产环境)

# 启用 IOMMU(在 /etc/default/grub 中添加)
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt"

# 更新 grub 并重启
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot

# 加载 vfio-pci 模块
sudo modprobe vfio-pci

# 验证 IOMMU 分组
ls /sys/kernel/iommu_groups/

4.2.3 绑定网卡到用户态驱动

使用 DPDK 提供的 dpdk-devbind.py 脚本进行绑定操作:

# 查看当前网卡状态
$RTE_SDK/usertools/dpdk-devbind.py --status

# 绑定网卡 0000:02:00.0 到 igb_uio
sudo $RTE_SDK/usertools/dpdk-devbind.py --bind=igb_uio 0000:02:00.0

# 绑定网卡 0000:02:00.1 到 vfio-pci
sudo $RTE_SDK/usertools/dpdk-devbind.py --bind=vfio-pci 0000:02:00.1

# 验证绑定结果
$RTE_SDK/usertools/dpdk-devbind.py --status | grep -A 3 "Network"
常见故障: 绑定 vfio-pci 时若报 "No IOMMU group available",请检查内核参数是否正确启用 IOMMU,并确认 BIOS 中已开启 VT-d / AMD-Vi。
网卡驱动绑定流程 内核原生驱动 (ixgbe/i40e/ice) 解绑 选择驱动 类型 igb_uio (无 IOMMU 环境) vfio-pci (生产环境推荐) dpdk-devbind.py 绑定

4.3 大页内存配置

DPDK 通过大页内存(HugePages)减少 TLB 缺失,提升数据包处理性能。推荐配置 2MB 或 1GB 大页,具体数量取决于 NUMA 节点数和预期内存占用。

4.3.1 配置 2MB 大页

# 临时配置(重启后失效)
echo 4096 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

# 永久配置(写入 /etc/sysctl.conf)
echo "vm.nr_hugepages=4096" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

# 挂载 hugetlbfs
sudo mkdir -p /mnt/huge
sudo mount -t hugetlbfs nodev /mnt/huge

# 自动挂载(写入 /etc/fstab)
echo "nodev /mnt/huge hugetlbfs defaults 0 0" | sudo tee -a /etc/fstab

4.3.2 配置 1GB 大页(推荐高性能场景)

# 在 GRUB 命令行中添加(需重启)
default_hugepagesz=1G hugepagesz=1G hugepages=4

# 完整 GRUB_CMDLINE_LINUX 示例
GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt default_hugepagesz=1G hugepagesz=1G hugepages=4"

# 更新 grub 并重启
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot

# 验证大页配置
grep HugePages /proc/meminfo
# 应看到 HugePages_Total: 4, Hugepagesize: 1048576 kB

4.3.3 NUMA 感知的大页分配

在多 NUMA 节点系统中,需为每个节点分别分配大页:

# 为 NUMA node0 分配 2048 个 2MB 大页
echo 2048 | sudo tee /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

# 为 NUMA node1 分配 2048 个 2MB 大页
echo 2048 | sudo tee /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages

# 验证 NUMA 分配
cat /sys/devices/system/node/node*/hugepages/hugepages-2048kB/nr_hugepages
性能建议: 对于 25G/100G 网卡,建议每个 NUMA 节点至少分配 4GB 大页(即 2048 个 2MB 页或 4 个 1GB 页),以确保 RSS 队列和 FDIR 规则表有足够的内存空间。
大页内存配置架构 物理内存 (DDR4/DDR5) 总容量: 64GB / 128GB / 256GB 2MB 大页池 nr_hugepages=4096 → 8GB 1GB 大页池 hugepages=4 → 4GB NUMA node0 NUMA node1 NUMA node0 NUMA node1

4.4 环境验证清单

完成上述步骤后,执行以下验证命令确保环境就绪:

验证项 命令 预期结果
DPDK 版本 pkg-config --modversion libdpdk 21.11
网卡绑定状态 dpdk-devbind.py --status 网卡显示 "drv=igb_uio" 或 "drv=vfio-pci"
大页总数 grep HugePages_Total /proc/meminfo ≥ 4096(2MB)或 ≥ 4(1GB)
NUMA 大页分布 cat /sys/devices/system/node/node*/hugepages/hugepages-2048kB/nr_hugepages 每个节点值 > 0
hugetlbfs 挂载 mount | grep huge 显示 /mnt/huge 挂载点
IOMMU 启用 dmesg | grep -i iommu 显示 "IOMMU enabled"
快速启动测试: 使用 DPDK 自带的 dpdk-testpmd 工具验证环境:
sudo $RTE_SDK/bin/dpdk-testpmd -l 0-3 -n 4 -- -i
若成功进入 testpmd 交互界面,则环境搭建完成。