伴随着5G时代的到来,DPDK这个集多家技术之长,将C10M的问题从软件层面完美解决的解决方案,立刻成为时代的宠儿。这其中关键的技术点,我们可以在EAL的初始化函数中看出一二。
在初始化的函数,大致做了下面几件事情
- 多线程和cpu的亲缘性设计。
- 大页表和内存池的划分。
- pci设备驱动的探测。
其实现方法的话:
- 读取/proc的kernel文件。
- 通过内嵌汇编语言,与寄存器进行交互。
rte_eal_init(int argc, char **argv)
{
int i, fctret, ret;
pthread_t thread_id;
static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
char cpuset[RTE_CPU_AFFINITY_STR_LEN];
char thread_name[RTE_MAX_THREAD_NAME_LEN];
/* checks if the machine is adequate */
/*目的:查看系统cpu的指令集是否支持
*实现:是使用CPUID汇编函数,获取cpu的信息
*/
if (!rte_cpu_is_supported()) {
rte_eal_init_alert("unsupported cpu type.");
rte_errno = ENOTSUP;
return -1;
}
/*目的:校验是否运行一次,
*实现:内嵌汇编语言cmpxchgl,比较寄存器里的数据,实现内存屏障,是dpdk原子锁的一种实现应用。
*/
if (!rte_atomic32_test_and_set(&run_once)) {
rte_eal_init_alert("already called initialization.");
rte_errno = EALREADY;
return -1;
}
/*目的:获取主线程的POSIX Thread id
*实现:通过一个回调函数f_pthread_self, 在加载真实的线程库地址时,对回调函数进行赋值
*/
thread_id = pthread_self();
/*目的:对环境抽象层的清空初始化
*实现:eal的信息(如内存,大页表,物理网卡的接管方式,终端,内存池等)保存在struct internal_config中。
*/
eal_reset_internal_config(&internal_config);
/* set log level as early as possible */
eal_log_level_parse(argc, argv);
/*目的:对cpu存储结构的初始化
*实现:对系统目录(/sys/devices/system/cpu)进行读取,对最大128个的cpu进行轮询访问,对于真实存在的cpu,
* 进行coreid、socketid和其他描述信息采集。
*/
if (rte_eal_cpu_init() < 0) {
rte_eal_init_alert("Cannot detect lcores.");
rte_errno = ENOTSUP;
return -1;
}
/*目的:对传参进行解析
*实现:支持长选项的参数解析函数getopt_long是各大开源项目的c语言首选函数解析入口
*/
fct