3. DPDK 编译与安装:解压源码、配置 Meson、编译、安装、设置环境变量与大页内存
在完成 DPDK Bonding 驱动配置之前,必须首先在目标系统上正确编译与安装 DPDK 环境。本章节将详细演示从源码解压到最终环境验证的完整流程,涵盖 Meson 构建系统的配置、NUMA 感知编译、环境变量持久化以及大页内存的预留与挂载。这些步骤是后续 Bonding 驱动加载与主备切换测试的基础。
3.1 解压 DPDK 源码
从 DPDK 官方仓库或长期支持(LTS)版本中获取源码。建议使用 21.11 LTS 或 22.11 LTS 版本,这些版本对 Bonding 驱动的支持最为稳定。
# 下载并解压 DPDK 21.11.2 LTS
wget https://fast.dpdk.org/rel/dpdk-21.11.2.tar.xz
tar -xvf dpdk-21.11.2.tar.xz
cd dpdk-21.11.2/
# 查看解压后的目录结构
ls -l
# 关键子目录:drivers/net/bonding/ lib/librte_ethdev/ app/test/
解压后的目录中,drivers/net/bonding/ 目录包含了 Bonding 驱动的 PMD(Poll Mode Driver)源码,lib/librte_ethdev/ 包含了以太网设备框架,app/test/ 包含了用于功能验证的测试程序。
| 路径 | 说明 |
|---|---|
drivers/net/bonding/ | Bonding 驱动 PMD 源码(主备、负载均衡、LACP 模式) |
lib/librte_ethdev/ | 以太网设备抽象层(rte_ethdev API) |
lib/librte_eal/ | 环境抽象层(内存、线程、PCI 枚举) |
app/test/ | 单元测试与功能验证程序 |
config/ | Meson 构建选项模板 |
3.2 配置 Meson 构建系统
DPDK 从 19.11 版本开始全面采用 Meson 构建系统。Meson 提供了灵活的交叉编译支持和模块化配置。配置时需指定目标架构、驱动白名单以及是否启用调试符号。
# 创建构建目录并进入
meson setup build
# 常用配置选项(在 build 目录外执行)
meson configure build \
-Dbuildtype=release \
-Dplatform=generic \
-Denable_docs=false \
-Denable_kmods=true \
-Dexamples=all \
-Dtests=true
# 查看所有可配置选项
meson configure build | grep -E "bonding|net_|kmod"
-Dplatform=generic:生成通用二进制,兼容性好;若已知 CPU 微架构,可指定native获得最佳性能。-Denable_kmods=true:编译内核模块(igb_uio、kni),用于用户态 I/O 驱动。-Dexamples=all:编译所有示例程序,包括l2fwd、l3fwd、bond示例。-Dtests=true:编译单元测试,用于验证 Bonding 驱动功能。
3.3 编译与安装
使用 Ninja 进行并行编译,然后安装到系统目录。编译时间取决于 CPU 核心数,建议使用 -j 参数充分利用多核。
# 编译 DPDK(使用所有 CPU 核心)
ninja -C build -j$(nproc)
# 安装到系统目录(默认 /usr/local)
sudo ninja -C build install
# 更新动态链接库缓存
sudo ldconfig
# 验证安装
pkg-config --modversion libdpdk
# 输出示例:21.11.2
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
ERROR: Problem encountered: missing libnuma | 未安装 libnuma-dev | sudo apt install libnuma-dev |
fatal error: rte_config.h: No such file | 构建目录未正确初始化 | 重新执行 meson setup build |
Could not find a package configuration file | 依赖的库未安装 | 安装 libpcap-dev、libelf-dev 等 |
build failed: linker error | 链接器版本不匹配 | 升级 binutils 或使用 -Dbuildtype=debug 重试 |
3.4 设置环境变量
DPDK 应用程序运行时需要知道目标环境的信息,包括 CPU 架构、内存通道数、PCI 设备白名单等。环境变量通过 export 设置,建议写入 ~/.bashrc 或 /etc/profile.d/dpdk.sh 实现持久化。
# 创建 DPDK 环境变量脚本
sudo tee /etc/profile.d/dpdk.sh << 'EOF'
# DPDK 环境变量配置
export RTE_SDK=/home/user/dpdk-21.11.2
export RTE_TARGET=x86_64-native-linuxapp-gcc
export DPDK_BUILD=$RTE_SDK/build
# 将 DPDK 库路径加入 LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$DPDK_BUILD/lib:$LD_LIBRARY_PATH
# 设置 PCI 白名单(可选,用于绑定特定网卡)
# export DPDK_PCI_WHITELIST="0000:02:00.0 0000:02:00.1"
EOF
# 使环境变量立即生效
source /etc/profile.d/dpdk.sh
# 验证环境变量
echo $RTE_SDK
echo $DPDK_BUILD
RTE_SDK:DPDK 源码根目录,用于示例程序和驱动编译。RTE_TARGET:目标架构标识,Meson 构建后通常为x86_64-native-linuxapp-gcc。DPDK_BUILD:构建输出目录,包含编译好的库和二进制文件。LD_LIBRARY_PATH:运行时动态库搜索路径,必须包含$DPDK_BUILD/lib。
3.5 配置大页内存
DPDK 使用大页内存(Hugepages)来减少 TLB 缺失,提高数据包处理性能。大页内存的配置包括预留页面数量、挂载 hugetlbfs 文件系统以及设置非特权用户访问权限。
# 1. 预留 2MB 大页(以 4GB 为例,需要 2048 个 2MB 页面)
echo 2048 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
# 2. 预留 1GB 大页(需要 BIOS 支持,预留 4 个 1GB 页面)
echo 4 | sudo tee /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
# 3. 挂载 hugetlbfs 文件系统
sudo mkdir -p /mnt/huge
sudo mount -t hugetlbfs nodev /mnt/huge
# 4. 设置开机自动挂载(写入 /etc/fstab)
echo "nodev /mnt/huge hugetlbfs defaults 0 0" | sudo tee -a /etc/fstab
# 5. 允许非 root 用户使用大页(设置组 ID)
sudo chmod 777 /mnt/huge
# 6. 验证大页配置
grep -i huge /proc/meminfo
# 输出示例:
# AnonHugePages: 0 kB
# ShmemHugePages: 0 kB
# HugePages_Total: 2048
# HugePages_Free: 2048
# HugePages_Rsvd: 0
# HugePages_Surp: 0
# Hugepagesize: 2048 kB
- 2MB 大页适用于大多数场景,1GB 大页适用于需要超大连续内存的应用程序(如流量重放)。
- 预留大页后需要重启系统才能生效(尤其是 1GB 大页)。
- 若使用
vfio-pci驱动,需确保 IOMMU 已启用,并设置iommu=pt内核参数。 - 大页内存不能被普通进程使用,必须通过 DPDK EAL 的
--huge-dir参数指定挂载点。
3.6 验证 DPDK 环境
完成编译、安装、环境变量设置和大页配置后,使用 DPDK 自带的 dpdk-test 或 l2fwd 示例程序验证环境是否正常工作。
# 1. 检查大页可用性
dpdk-test -l 0-1 -n 4 --huge-dir /mnt/huge -- -i
# 进入交互界面后输入 "quit" 退出
# 2. 运行 l2fwd 示例(需要绑定两个网卡)
cd $RTE_SDK/examples/l2fwd
make
sudo ./build/l2fwd -l 0-1 -n 4 -- -p 0x3
# 3. 查看 DPDK 版本与构建信息
$DPDK_BUILD/app/dpdk-testpmd -l 0-1 -n 4 -- -i
testpmd> show port info all
testpmd> quit
| 检查项 | 验证命令 | 预期结果 |
|---|---|---|
| DPDK 版本 | pkg-config --modversion libdpdk | 显示 21.11.2 或对应版本 |
| 大页总数 | grep HugePages_Total /proc/meminfo | ≥ 2048(2MB 页面) |
| 大页空闲 | grep HugePages_Free /proc/meminfo | 与 Total 一致(未使用前) |
| hugetlbfs 挂载 | mount | grep hugetlbfs | 显示 /mnt/huge |
| EAL 初始化 | dpdk-test -l 0 -n 4 | 无错误输出,EAL 初始化成功 |
| 动态库加载 | ldconfig -p | grep dpdk | 显示 librte_*.so 路径 |