在上一篇章节中,我们介绍了思科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;
函数路径介绍:thread0函数位于vlib/unix/main.c中
函数功能介绍:主要是调用vlib/main.c的vlib_main()函数。
代码逻辑展示:
static uword
thread0 (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 void
vlib_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()函数的处理逻辑,谢谢!
作者简介
作者:通信行业搬砖工