DPU网络开发SDK——DPDK(二)
admin
2024-05-15 04:44:03
0

Hello world

上一次的文章中主要介绍了DPDK是什么,主要用在什么地方。作为一个SDK,DPDK提供了大量的function接口用于网络转发面程序的编写。接下来的几篇文章,我们会基于DPDK程序的实例,以剖析关键function接口的方式逐步分析DPDK的实现机制,以此来熟悉DPDK的整个样貌。由于DPDK的版本发生过巨大的变化,涉及到编译方式等的改变,之后的分析统一基于20.11.0这个版本进行。

static int lcore_hello(__rte_unused void *arg) {unsigned lcore_id;lcore_id = rte_lcore_id();printf("hello from core %u\n", lcore_id);return 0;
}int main(int argc, char **argv) {int ret;unsigned lcore_id;ret = rte_eal_init(argc, argv);if (ret < 0)rte_panic("Cannot init EAL\n");RTE_LCORE_FOREACH_WORKER(lcore_id) {rte_eal_remote_launch(lcore_hello, NULL, lcore_id);}lcore_hello(NULL);rte_eal_mp_wait_lcore();return 0;
}

我们以DPDK版本的“hello world”为例开始我们的分析过程,其代码内容如上(省略头文件)。

进入主函数之后,首先需要调用的是rte_eal_init,该函数的作用是用来初始化DPDK的运行时环境(runtime environment, rte),在DPDK中称为环境抽象层(environment abstract layer, eal)。该初始化过程中会提取命令行参数列表中与DPDK相关的参数进行解析,初始化各类全局数据结构,初始化内存等。该过程涉及到的初始化内容很多,是接下来的几篇DPDK分析文章中会重点分析的内容。

DPDK的eal环境初始化完毕之后,会在各处理核(lcore)上启动各线程,DPDK用RTE_LCORE_FOREACH_WORKER这个宏定义来遍历所有的worker处理核,并在该处理核上启动线程的入口函数。本例中的入口函数是lcore_hello,DPDK通过rte_eal_remote_launch将线程入口函数与处理核进行绑定,绑定之后,在DPDK进程结束前,该线程会独占该处理核且不会有其他线程调度到该处理核上运行。

与worker处理核相对应的是main处理核,在执行DPDK进程时,进程被调度到哪个处理核上执行,该处理核就是main处理核,即main处理核承担了初始化DPDK的任务。在本例中,main函数在各worker处理核上启动线程之后,同样执行了lcore_hello,并且调用rte_eal_mp_wait_lcore等待所有线程执行完毕之后再退出。

lcore_hello的工作仅为获取当前处理核的ID并打印到控制台,在DPDK中处理核的ID从0开始连续编号,最大支持的处理核数量在编译DPDK的lib库时由配置文件指定为宏定义。运行过程中DPDK进程实际占用的处理核与CPU的Processor的对应列表则是由启动DPDK时的参数指定的,rte_eal_init会对此进行解析并初始化相关处理结构。

rte_eal_init()

rte_eal_init的整个初始化过程非常长,此处的分析过程中会尽可能将重点过程保留下来,对某些细节内容则先忽略。因rte_eal_init的代码非常长,此处不做粘贴处理,请自行阅读源代码。

1. 获取两个全局配置

DPDK中有两个全局配置的变量,类型分别为struct rte_config和struct internal_config。数据结构的定义分别在lib/librte_eal/common目录下的eal_private.h和eal_internal_cfg.h两个文件中,变量定义在eal_common_config.c文件中,并提供了ret_eal_get_configuration()和eal_get_internal_configuration()两个接口用于获取这两个配置的变量。

在rte_eal_init中,首先获取这两个全局变量,用于记录经参数解析后的配置及初始化的其他数据结构等。

2. 检查主机是否满足运行要求

该项检查主要是检查CPU的特性,执行入口为rte_cpu_is_supported()。该function中,会根据编译时定义的宏RTE_COMPILE_TIME_CPUFLAGS当中指定cpuflag列表,去依次检查当前主机的CPU是否支持这些flag特性,出现不支持的特性时则会以错误返回。该function的实现是分CPU架构的。

3. 确保初始化过程只运行了一次

通过static类型的变量run_once和来标识是否init是否已经执行过了,在一个DPDK进程中rte_eal_init只能执行一次。

4. 初始化internal_config

将全局配置变量internal_config中相关成员的值设置为默认值。

5. 设置日志级别

调用eal_log_level_parse()负责日志级别的解析,通过解析命令行参数"--log-leve"确定以什么级别打印日志,并将日志等级存入internal_config中。

由于日志越早打印越有助于在出现问题时及时定位,所以DPDK在初始化阶段的早期就解析了日志级别,而其他的命令行参数则在随后才做解析。

在下期我们将继续进行rte_eal_init的过程分析。

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
A.机器学习入门算法(三):基... 机器学习算法(三):K近邻(k-nearest neigh...
数字温湿度传感器DHT11模块... 模块实例https://blog.csdn.net/qq_38393591/article/deta...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
Redis 所有支持的数据结构... Redis 是一种开源的基于键值对存储的 NoSQL 数据库,支持多种数据结构。以下是...
win下pytorch安装—c... 安装目录一、cuda安装1.1、cuda版本选择1.2、下载安装二、cudnn安装三、pytorch...
MySQL基础-多表查询 文章目录MySQL基础-多表查询一、案例及引入1、基础概念2、笛卡尔积的理解二、多表查询的分类1、等...
keil调试专题篇 调试的前提是需要连接调试器比如STLINK。 然后点击菜单或者快捷图标均可进入调试模式。 如果前面...
MATLAB | 全网最详细网... 一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点&#...
IHome主页 - 让你的浏览... 随着互联网的发展,人们越来越离不开浏览器了。每天上班、学习、娱乐,浏览器...
TCP 协议 一、TCP 协议概念 TCP即传输控制协议(Transmission Control ...
营业执照的经营范围有哪些 营业执照的经营范围有哪些 经营范围是指企业可以从事的生产经营与服务项目,是进行公司注册...
C++ 可变体(variant... 一、可变体(variant) 基础用法 Union的问题: 无法知道当前使用的类型是什...
血压计语音芯片,电子医疗设备声... 语音电子血压计是带有语音提示功能的电子血压计,测量前至测量结果全程语音播报࿰...
MySQL OCP888题解0... 文章目录1、原题1.1、英文原题1.2、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3...
【2023-Pytorch-检... (肆十二想说的一些话)Yolo这个系列我们已经更新了大概一年的时间,现在基本的流程也走走通了,包含数...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
记录--我在前端干工地(thr... 这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 前段时间接触了Th...
43 openEuler搭建A... 文章目录43 openEuler搭建Apache服务器-配置文件说明和管理模块43.1 配置文件说明...