2. Hello World

任务目标

编写一个最小DPDK程序,调用rte_eal_init()完成环境抽象层(EAL)初始化,随后遍历可用逻辑核并打印其ID与套接字信息,以此验证DPDK运行环境可用并理解EAL初始化在DPDK程序中的入口作用。

环境依赖

  • DPDK版本:20.11或更高(本案例使用稳定LTS版本即可)
  • 系统:Linux(x86_64或ARM64),内核支持hugepage与uio/vfio驱动
  • 编译依赖:meson、ninja、pkg-config、C编译器(gcc/clang)
  • 运行前需完成:hugepage挂载(如/dev/hugepages)、DPDK驱动绑定(本案例仅需igb_uio或vfio-pci,但无网卡设备也可运行)

完整代码

// hello_eal.c
#include <rte_eal.h>
#include <rte_lcore.h>
#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    int ret;
    unsigned lcore_id;

    // 1. 初始化EAL,解析传入的EAL参数(如 -l, -m, --huge-dir 等)
    ret = rte_eal_init(argc, argv);
    if (ret < 0) {
        fprintf(stderr, "Error: EAL init failed (code=%d)\n", ret);
        return -1;
    }

    // 2. 打印EAL初始化成功信息
    printf("EAL initialized successfully.\n");

    // 3. 遍历所有可用的逻辑核并打印信息
    printf("Available lcores:\n");
    RTE_LCORE_FOREACH(lcore_id) {
        printf("  lcore %u (socket %u)\n",
               lcore_id, rte_lcore_to_socket_id(lcore_id));
    }

    // 4. 打印主逻辑核
    printf("Main lcore: %u\n", rte_get_main_lcore());

    return 0;
}

编译与运行

# 使用pkg-config获取编译参数(确保DPDK已安装并导出环境变量)
cc -o hello_eal hello_eal.c $(pkg-config --cflags --libs libdpdk)

# 运行(需root权限或设置合适权限;-l 指定使用的逻辑核)
sudo ./hello_eal -l 0-3

若DPDK未通过pkg-config导出,可手动指定-I/usr/local/include/dpdk -L/usr/local/lib -lrte_eal -lrte_kvargs -lrte_telemetry等链接参数,具体路径以实际安装位置为准。

验证方法

  • 预期输出:程序打印EAL initialized successfully.,随后列出-l参数指定的逻辑核ID及对应NUMA socket编号,最后打印主核ID(通常为0)。例如使用-l 0-3时,预期输出包含lcore 0 (socket 0)至lcore 3 (socket 0)(单socket机器)。
  • 通过条件:程序正常退出(exit code 0),输出中每个逻辑核ID与-l参数范围一致,且无EAL初始化错误信息。
  • 常见错误排查:若报EAL: Cannot get hugepage information,检查hugepage是否挂载;若报EAL: unsupported cpu core map,检查-l参数是否超出系统可用核数。

关键说明

rte_eal_init()是DPDK程序的强制入口,负责内存池初始化、PCI设备探测、逻辑核映射等底层工作。其返回值表示成功解析的参数个数(不含EAL参数),负值表示失败。本案例仅演示EAL初始化与逻辑核枚举,不涉及网卡收发,因此无需绑定任何PCI设备即可运行。