1. 环境搭建与基础验证
任务目标
本案例完成DPDK与RDMA(InfiniBand/RoCE)开发环境的搭建,并通过基础功能验证确保后续案例可运行。验证内容包括:DPDK的EAL初始化与内存池操作、RDMA设备的查询与状态确认。
环境依赖
- 操作系统:Ubuntu 22.04 LTS(内核≥5.15)
- DPDK版本:22.11 LTS
- RDMA驱动:MLNX_OFED(Mellanox网卡)或系统自带rdma-core(RoCE网卡)
- 硬件:支持RDMA的网卡(Mellanox CX-5/CX-6或RoCE v2网卡)
- 编译工具:gcc、make、pkg-config、libnuma-dev
安装步骤
# 1. 安装系统依赖
sudo apt update && sudo apt install -y build-essential libnuma-dev python3-pip pkg-config
# 2. 编译安装DPDK
wget https://fast.dpdk.org/rel/dpdk-22.11.tar.xz
tar xf dpdk-22.11.tar.xz && cd dpdk-22.11
meson setup build && ninja -C build
sudo ninja -C build install
sudo ldconfig
# 3. 配置HugePages(DPDK必需)
echo 1024 | sudo tee /proc/sys/vm/nr_hugepages
sudo mkdir -p /mnt/huge
sudo mount -t hugetlbfs pagesize=1GB /mnt/huge
# 4. 加载RDMA内核模块
sudo modprobe mlx5_core # Mellanox网卡
# 或 sudo modprobe rdma_rxe # 软RoCE(无硬件时调试用)
# 5. 绑定网卡到DPDK(可选,仅DPDK轮询模式需要)
sudo dpdk-devbind.py --status # 查看网卡PCI地址
sudo dpdk-devbind.py --bind=mlx5_core 0000:03:00.0 # 示例,按实际地址修改
核心验证代码
// env_check.c - DPDK与RDMA环境验证
#include <rte_eal.h>
#include <rte_mempool.h>
#include <rte_lcore.h>
#include <infiniband/verbs.h>
#include <stdio.h>
#include <string.h>
#define POOL_SIZE 8192
#define CACHE_SIZE 256
int main(int argc, char *argv[]) {
// 1. DPDK EAL初始化
int ret = rte_eal_init(argc, argv);
if (ret < 0) {
printf("EAL初始化失败: %s\n", rte_strerror(rte_errno));
return -1;
}
printf("[PASS] EAL初始化成功, 检测到 %u 个核\n", rte_lcore_count());
// 2. 内存池创建与验证
struct rte_mempool *mp = rte_mempool_create("test_pool", POOL_SIZE,
sizeof(uint64_t), CACHE_SIZE, 0, NULL, NULL, NULL, NULL,
rte_socket_id(), 0);
if (!mp) {
printf("内存池创建失败\n");
return -1;
}
printf("[PASS] 内存池创建成功, 可用对象: %u\n", rte_mempool_avail_count(mp));
// 3. 内存池对象分配/释放测试
void *obj = NULL;
if (rte_mempool_get(mp, &obj) == 0) {
memset(obj, 0xAB, sizeof(uint64_t));
rte_mempool_put(mp, obj);
printf("[PASS] 内存池对象分配/释放正常\n");
} else {
printf("[FAIL] 内存池对象分配失败\n");
return -1;
}
rte_mempool_free(mp);
// 4. RDMA设备查询
struct ibv_device **dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
printf("[FAIL] 未检测到RDMA设备\n");
return -1;
}
int dev_count = 0;
for (int i = 0; dev_list[i]; i++) {
struct ibv_context *ctx = ibv_open_device(dev_list[i]);
if (!ctx) continue;
struct ibv_device_attr attr;
if (ibv_query_device(ctx, &attr) == 0) {
printf("[PASS] RDMA设备 %d: %s, 端口数=%u, 固件版本=%s\n",
dev_count++, ibv_get_device_name(dev_list[i]),
attr.phys_port_cnt, attr.fw_ver);
}
ibv_close_device(ctx);
}
ibv_free_device_list(dev_list);
if (dev_count == 0) {
printf("[FAIL] 没有可用的RDMA设备\n");
return -1;
}
// 5. 清理EAL
rte_eal_cleanup();
printf("环境验证全部通过\n");
return 0;
}
编译与运行
# 编译(需root权限运行)
gcc -o env_check env_check.c $(pkg-config --cflags --libs libdpdk) -libverbs
sudo ./env_check
# 预期输出(示例,具体数值因环境而异):
# [PASS] EAL初始化成功, 检测到 8 个核
# [PASS] 内存池创建成功, 可用对象: 8192
# [PASS] 内存池对象分配/释放正常
# [PASS] RDMA设备 0: mlx5_0, 端口数=1, 固件版本=16.35.2000
# 环境验证全部通过
验证判定标准
- 程序输出包含所有
[PASS]标记,且最后一行显示“环境验证全部通过” - RDMA设备查询结果中端口数≥1,说明网卡驱动加载正常
- 若使用软RoCE(rdma_rxe),设备名显示为
rxe0,端口数为1 - DPDK内存池可用对象数等于创建时指定的8192,说明HugePages配置正确
常见问题排查
- EAL初始化失败:确认已配置HugePages(
cat /proc/meminfo | grep HugePages),且当前用户对/mnt/huge有读写权限 - 未检测到RDMA设备:执行
ibv_devinfo确认驱动已加载;Mellanox网卡需安装MLNX_OFED驱动 - 编译报错找不到头文件:确认
pkg-config --cflags libdpdk有输出,必要时设置PKG_CONFIG_PATH=/usr/local/lib/pkgconfig - 权限不足:DPDK和RDMA操作均需root权限,使用
sudo运行