01=
上期内容回顾

在上一篇章节中,我们介绍了思科VPP软件核心函数vlib_unix_main初始化介绍,

     

文章链接如下:

 深入浅出思科VPP24.02系列:vlib_unix_main初始化介绍

其初始化流程如下所示:

接下来我们将继续介绍上一章节中:clib_calljmp在开启thread0的同时也向thread0这个线程传入了栈; 之后的业务流程

代码片段:i = clib_calljmp (thread0, (uword) vm,        (void *) (vlib_thread_stacks[0] +            VLIB_THREAD_STACK_SIZE));  return i;
02=
VPP函数thread0介绍

函数路径介绍:thread0函数位于vlib/unix/main.c中

函数功能介绍:主要是调用vlib/main.c的vlib_main()函数。

代码逻辑展示:

static uwordthread0 (uword arg){  vlib_main_t *vm = (vlib_main_t *) arg;  vlib_global_main_t *vgm = vlib_get_global_main ();  unformat_input_t input;  int i;
vlib_process_finish_switch_stack (vm);
unformat_init_command_line (&input, (char **) vgm->argv); i = vlib_main (vm, &input); unformat_free (&input);
return i;}

结构体vlib_global_main_t介绍

typedef struct vlib_global_main_t{  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
/* Per-thread Mains */ vlib_main_t **vlib_mains;
/* Name for e.g. syslog. */ char *name;
/* full path to main executable */ char *exec_path;
/* command line arguments */ u8 **argv;
/* post-mortem callbacks */ void (**post_mortem_callbacks) (void);
/* * Need to call vlib_worker_thread_node_runtime_update before * releasing worker thread barrier. */ int need_vlib_worker_thread_node_runtime_update;
/* Command line interface. */ vlib_cli_main_t cli_main;
/* Node registrations added by constructors */ vlib_node_registration_t *node_registrations;
/* Event logger. */ elog_main_t elog_main; u32 configured_elog_ring_size;
/* Packet trace capture filter */ vlib_trace_filter_t trace_filter;
/* List of init functions to call, setup by constructors */ _vlib_init_function_list_elt_t *init_function_registrations; _vlib_init_function_list_elt_t *main_loop_enter_function_registrations; _vlib_init_function_list_elt_t *main_loop_exit_function_registrations; _vlib_init_function_list_elt_t *worker_init_function_registrations; _vlib_init_function_list_elt_t *num_workers_change_function_registrations; _vlib_init_function_list_elt_t *api_init_function_registrations; vlib_config_function_runtime_t *config_function_registrations;
/* Hash table to record which init functions have been called. */ uword *init_functions_called;
} vlib_global_main_t;

结构体参数功能介绍:

1、CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); 其工程上的含义是:指定结构体按照64字节对齐,提高缓存命中。

关于CPU cacheline相关的基础知识介绍:在微机原理专业课上介绍是由tag、index和offset三者组合就可以唯一确定一个cache地址。

假设我们读取cache line的数据,64Bytes的数据,每个cache line的大小为8个字节,因此我们在读取的时候可以把这块数据看成一个数组,因此在使用对齐之后,避免内存空洞的出现,从而提高了读取的效率。

2、vlib_main_t **vlib_mains; 其工程意义为每个线程维护的mains,因为我们的vpp是使用intel DPDK的 run-to-complete的RTC模式,每个核处理自己的业务逻辑。关于RTC模式,在上一章节已经介绍,本次就不再多叙述。

3、vlib_node_registration_t *node_registrations; 节点注册相关功能,这个在后期章节中继续介绍。

4、elog相关功能,该部分主要是用来配置elog日志功能的参数;

  elog_main_t elog_main;  u32 configured_elog_ring_size;

5、vlib_trace_filter_t trace_filter; 该部分主要是和trace功能相关,主要是介绍报文在vpp处理的路径等可维护性相关的功能相关。

6、该部分主要涉及初始化函数等相关功能的介绍,在后期章节中介绍

  _vlib_init_function_list_elt_t *init_function_registrations;  _vlib_init_function_list_elt_t *main_loop_enter_function_registrations;  _vlib_init_function_list_elt_t *main_loop_exit_function_registrations;  _vlib_init_function_list_elt_t *worker_init_function_registrations;  _vlib_init_function_list_elt_t *num_workers_change_function_registrations;  _vlib_init_function_list_elt_t *api_init_function_registrations;  vlib_config_function_runtime_t *config_function_registrations;

处理函数vlib_process_finish_switch_stack介绍

该部分主要是Sanitizers工具,发现代码bug相关的逻辑,在使能该特性的前提下使用。

static_always_inline voidvlib_process_finish_switch_stack (vlib_main_t * vm){#ifdef CLIB_SANITIZE_ADDR  const void *bottom_old;  size_t size_old;
__sanitizer_finish_switch_fiber (&vm->asan_stack_save, &bottom_old, &size_old);#endif}

参数传入vlib_main介绍

该部分逻辑是将参数,格式化至input变量,传入vlib_main函数的逻辑

  unformat_init_command_line (&input, (char **) vgm->argv);  i = vlib_main (vm, &input);  unformat_free (&input);

本次章节thread0的处理逻辑就讲完了,小伙伴们,你们学会了吗?

课间休息时间,放松一下心情!

下一章节,我们将继续介绍vlib_main()函数的处理逻辑,谢谢!

作者简介

作者:通信行业搬砖工