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;本案例仅打印检测值,不涉及实际内存分配。