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运行