3. EAL初始化参数解析

任务目标

编写一个最小DPDK程序,解析EAL初始化参数(lcore掩码、内存通道数、内存大小等),并打印解析结果,以理解这些参数对DPDK运行行为的影响。

环境与依赖

  • DPDK版本:20.11+(本案例使用rte_eal_init返回值与rte_config获取解析结果)
  • 编译依赖:libdpdk-dev(或DPDK源码编译后的lib/librte_eal)
  • 运行权限:需要root权限(或设置hugepages并解锁内存锁限制)

核心实现

#include <rte_eal.h>
#include <rte_lcore.h>
#include <rte_config.h>
#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[]) {
    // 初始化EAL,传入命令行参数(含EAL参数)
    int ret = rte_eal_init(argc, argv);
    if (ret < 0) {
        printf("EAL init failed: %d\n", ret);
        return -1;
    }

    // 获取EAL配置结构
    const struct rte_config *cfg = rte_eal_get_configuration();

    // 1. lcore掩码解析
    uint64_t lcore_mask = cfg->lcore_role[0]; // 实际掩码需遍历lcore_role
    printf("=== EAL 参数解析结果 ===\n");
    printf("可用lcore数量: %u\n", rte_lcore_count());
    printf("lcore掩码(bitmap): ");
    unsigned int lcore_id;
    RTE_LCORE_FOREACH(lcore_id) {
        printf("%u ", lcore_id);
    }
    printf("\n");

    // 2. 内存通道数
    printf("内存通道数: %u\n", cfg->mem_config->nchannel);

    // 3. 内存大小(MB)
    uint64_t mem_mb = rte_eal_get_physmem_size() / (1024 * 1024);
    printf("检测到的物理内存: %llu MB\n", (unsigned long long)mem_mb);

    // 4. 主lcore
    printf("主lcore: %u\n", rte_get_main_lcore());

    // 5. 显式解析常用EAL参数(通过rte_eal_get_configuration)
    printf("hugepage大小: %u KB\n", cfg->mem_config->hugepage_sz / 1024);

    // 清理
    rte_eal_cleanup();
    return 0;
}

编译与运行

# 编译(假设DPDK已安装,pkg-config可用)
gcc -o eal_parse eal_parse.c $(pkg-config --cflags --libs libdpdk)

# 运行(需要root,并预留hugepages)
echo 64 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
mount -t hugetlbfs pagesize=2M /dev/hugepages 2>/dev/null || true

# 带EAL参数运行
./eal_parse -l 0-3 -n 2 --socket-mem 128

验证方法

  • 预期输出(与上述命令对应):可用lcore数量: 4,lcore掩码: 0 1 2 3,内存通道数: 2,主lcore: 0。
  • 判定通过条件:程序正常退出(返回0),且输出的lcore数量与-l 0-3指定的4个一致;内存通道数与-n 2一致。
  • 参数变更测试:改用-l 0-1 -n 4运行,观察输出中lcore数量变为2、通道数变为4,验证参数确实被EAL解析生效。

关键说明

  • rte_eal_init会从argv中剥离并解析所有EAL参数(以-开头),剩余参数留给应用使用。
  • rte_config结构体中的lcore_role数组标记每个lcore的角色(ROLE_RTE表示可用),实际掩码需遍历该数组而非直接读取一个整数。
  • 内存通道数nchannel在rte_mem_config中,反映内存控制器通道配置,影响rte_mempool的通道交错策略。
  • 若未指定--socket-mem,EAL会尝试映射所有可用hugepage;本案例仅打印检测值,不涉及实际内存分配。