vpp框架中的结构体分析

vlib_main_t

typedef struct vlib_main_t

{

  CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); //指定结构体按照64字节对齐,提高缓存命中

  /*指令级别的时间. */

  clib_time_t clib_time;

  /*主线程时间偏移*/

  f64 time_offset;

  f64 time_last_barrier_release;

 

  /*最后一个节点调度的时间戳. */

  u64 cpu_time_last_node_dispatch;

 

  /* 开启主线程时的时间戳. */

  u64 cpu_time_main_loop_start;

 

  /* 主循环递增次数. */

  u32 main_loop_count;

 

  /*主循环中vectorsnodes计数. */

  u32 main_loop_vectors_processed;

  u32 main_loop_nodes_processed;

 

  /* 内部节点vectorscalls*/

  u64 internal_node_vectors;

  u64 internal_node_calls;

  u64 internal_node_vectors_last_clear;

  u64 internal_node_calls_last_clear;

 

  /* 即时向量速率 */

  u32 internal_node_last_vectors_per_main_loop;

 

  /* 主循环 hw/sw 性能计数器*/

  void (**vlib_node_runtime_perf_counter_cbs) (struct vlib_main_t *,

                                                      u64 *, u64 *,

                                                      vlib_node_runtime_t *,

                                                      vlib_frame_t *, int);

  void (**vlib_node_runtime_perf_counter_cb_tmp) (struct vlib_main_t *,

                                                          u64 *, u64 *,

                                                          vlib_node_runtime_t *,

                                                          vlib_frame_t *, int);

  /* Every so often we switch to the next counter. */

#define VLIB_LOG2_MAIN_LOOPS_PER_STATS_UPDATE 7

 

  /*跳转退出主循环. */

  u32 main_loop_exit_set;

  /* Set e.g. in the SIGTERM signal handler, checked in a safe place... */

  volatile u32 main_loop_exit_now;

  clib_longjmp_t main_loop_exit;

#define VLIB_MAIN_LOOP_EXIT_NONE 0

#define VLIB_MAIN_LOOP_EXIT_PANIC 1

  /* Exit via CLI. */

#define VLIB_MAIN_LOOP_EXIT_CLI 2

 

  /*退出主循环时候的出错标记. */

  clib_error_t *main_loop_error;

 

  /*名称,例如:syslog. */

  char *name;

 

  /* 堆的开始. */

  void *heap_base;

 

  /* 截断版本,帧的索引*/

  void *heap_aligned_base;

 

  /* 堆的大小 */

  uword heap_size;

 

  /* 缓存区主体结构. */

  vlib_buffer_main_t *buffer_main;

 

  /* 物理内存主体结构. */

  vlib_physmem_main_t physmem_main;

 

  /* 节点编排主体结构. */

  vlib_node_main_t node_main;

 

  /* 命令行接口. */

  vlib_cli_main_t cli_main;

 

  /* 包的追踪缓冲区. */

  vlib_trace_main_t trace_main;

 

  /* Pcap 调度追踪 */

  pcap_main_t dispatch_pcap_main;

  uword dispatch_pcap_enable;

  u32 *dispatch_buffer_trace_nodes;

  u8 *pcap_buffer;

 

  /* pcap 发送/接收跟踪 */

  vnet_pcap_t pcap;

 

  /* 错误处理. */

  vlib_error_main_t error_main;

 

  /* Punt packets to underlying operating system for when fast switching

     code does not know what to do. */

  void (*os_punt_frame) (struct vlib_main_t * vm,

                             struct vlib_node_runtime_t * node,

                             vlib_frame_t * frame);

 

  /* Stream index to use for distribution when MC is enabled. */

  u32 mc_stream_index;

 

  vlib_one_time_waiting_process_t *procs_waiting_for_mc_stream_join;

 

  /* 事件记录器. */

  elog_main_t elog_main;

 

  /* 事件记录器跟踪标志 */

  int elog_trace_api_messages;

  int elog_trace_cli_commands;

  int elog_trace_graph_dispatch;

  int elog_trace_graph_circuit;

  u32 elog_trace_graph_circuit_node_index;

 

  /* 节点调用和返回的时间类型. */

  elog_event_type_t *node_call_elog_event_types;

  elog_event_type_t *node_return_elog_event_types;

 

  elog_event_type_t *error_elog_event_types;

 

  /*种子随机生成器. */

  uword random_seed;

 

  /* 用于各种用途的随机数缓冲区. */

  clib_random_buffer_t random_buffer;

 

  /*用来记录调用了哪些init函数的散列表. */

  uword *init_functions_called;

 

  /* thread, cpu and numa_node 索引 */

  u32 thread_index;

  u32 cpu_id;

  u32 numa_node;

 

  /*要调用的init函数列表,由构造函数设置*/

  _vlib_init_function_list_elt_t *init_function_registrations;

  _vlib_init_function_list_elt_t *worker_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 *api_init_function_registrations;

  vlib_config_function_runtime_t *config_function_registrations;

 

  /*控制平面API队列信号挂起,长度指示*/

  volatile u32 queue_signal_pending;

  volatile u32 api_queue_nonempty;

  void (*queue_signal_callback) (struct vlib_main_t *);

  u8 **argv;

 

  /* Top of (worker) dispatch loop callback */

  void (**volatile worker_thread_main_loop_callbacks) (struct vlib_main_t *);

  void (**volatile worker_thread_main_loop_callback_tmp)

    (struct vlib_main_t *);

  clib_spinlock_t worker_thread_main_loop_callback_lock;

 

  /* debugging */

  volatile int parked_at_barrier;

 

  /* 事后日志转存 */

  int elog_post_mortem_dump;

 

  /*

   * Need to call vlib_worker_thread_node_runtime_update before

   * releasing worker thread barrier. Only valid in vlib_global_main.

   */

  int need_vlib_worker_thread_node_runtime_update;

 

  /*

   * Barrier epoch - Set to current time, each time barrier_sync or

   * barrier_release is called with zero recursion.

   */

  f64 barrier_epoch;

 

  /* Earliest barrier can be closed again */

  f64 barrier_no_close_before;

 

  /* 检测帧队列 */

  volatile uword check_frame_queues;

 

  /* RPC 请求, 仅仅是主线程*/

  uword *pending_rpc_requests;

  uword *processing_rpc_requests;

  clib_spinlock_t pending_rpc_lock;

 

} vlib_main_t;

 

//注册节点,调用的是宏定义

VLIB_REGISTER_NODE (abf_ip6_node) =

{

  .function = abf_input_ip6,

  .name = "abf-input-ip6",

  .vector_size = sizeof (u32),

  .format_trace = format_abf_input_trace,

  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = 0,

  .n_next_nodes = ABF_N_NEXT,

  .next_nodes =

  {

    [ABF_NEXT_DROP] = "error-drop",

  }

};

 

//…__VA_ARGS__为可变参数,##连接字符串

//__attribute__((__constructor__))修饰函数main函数之前执行

// __attribute__((__destructor__)) 修饰函数在main函数结束之后执行

#define VLIB_REGISTER_NODE(x,...)                                  \

    __VA_ARGS__ vlib_node_registration_t x;                         \

static void __vlib_add_node_registration_##x (void)                     \

    __attribute__((__constructor__)) ;                               \

static void __vlib_add_node_registration_##x (void)                     \

{                                                               \

    vlib_main_t * vm = vlib_get_main();                              \

    x.next_registration = vm->node_main.node_registrations;             \

    vm->node_main.node_registrations = &x;                          \

}                                                               \

static void __vlib_rm_node_registration_##x (void)                      \

    __attribute__((__destructor__)) ;                                 \

static void __vlib_rm_node_registration_##x (void)                      \

{                                                               \

    vlib_main_t * vm = vlib_get_main();                               \

    VLIB_REMOVE_FROM_LINKED_LIST (vm->node_main.node_registrations, \

                                  &x, next_registration);            \

}                                                                \

__VA_ARGS__ vlib_node_registration_t x

//定义

 

//构造init函数列表

#define VLIB_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,init)

#define VLIB_WORKER_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,worker_init)

 

#define VLIB_MAIN_LOOP_ENTER_FUNCTION(x) \

  VLIB_DECLARE_INIT_FUNCTION(x,main_loop_enter)

#define VLIB_MAIN_LOOP_EXIT_FUNCTION(x) \

VLIB_DECLARE_INIT_FUNCTION(x,main_loop_exit)

 

#define VLIB_API_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,api_init)

 

#define VLIB_CONFIG_FUNCTION(x,n,...)

 

启动调用vlib_call_all_init_functions函数加载执行。

vlib_node_main_t

typedef struct

{

  /* 公共节点. */

  vlib_node_t **nodes;

 

  /* 按照节点名散列的节点索引. */

  uword *node_by_name;

 

  u32 flags;

#define VLIB_NODE_MAIN_RUNTIME_STARTED (1 << 0)

 

  /* 按类型为缓存位置分隔的节点.

     Does not apply to nodes of type VLIB_NODE_TYPE_INTERNAL. */

  vlib_node_runtime_t *nodes_by_type[VLIB_N_NODE_TYPE];

 

  /* 带有挂起中断的输入节点的节点运行时索引. */

  u32 *pending_interrupt_node_runtime_indices;

  clib_spinlock_t pending_interrupt_lock;

 

  /* 输入节点切换从/打断/轮询方式当平均向量长度高于/低于轮询/中断阈值. */

  u32 polling_threshold_vector_length;

  u32 interrupt_threshold_vector_length;

 

  /* 下一帧向量. */

  vlib_next_frame_t *next_frames;

 

  /* 等待调用的内部节点帧的向量. */

  vlib_pending_frame_t *pending_frames;

 

  /* 用于调度基于时间的节点调度的定时轮. */

  void *timing_wheel;

 

  vlib_signal_timed_event_data_t *signal_timed_event_data_pool;

 

  /* 通过timing_wheel_advance添加的不透明数据向量. */

  u32 *data_from_advancing_timing_wheel;

 

  /* CPU time of next process to be ready on timing wheel. */

  f64 time_next_process_ready;

 

  /* Vector of process nodes.

     One for each node of type VLIB_NODE_TYPE_PROCESS. */

  vlib_process_t **processes;

 

  /* Current running process or ~0 if no process running. */

  u32 current_process_index;

 

  /* Pool of pending process frames. */

  vlib_pending_frame_t *suspended_process_frames;

 

  /* Vector of event data vectors pending recycle. */

  void **recycled_event_data_vectors;

 

  /* 每个状态的当前节点数. */

  u32 input_node_counts_by_state[VLIB_N_NODE_STATE];

 

  /* Hash of (scalar_size,vector_size) to frame_sizes index. */

  uword *frame_size_hash;

 

  /* Per-size frame allocation information. */

  vlib_frame_size_t *frame_sizes;

 

  /* 清除最后一个节点运行时的时间统计信息. */

  f64 time_last_runtime_stats_clear;

 

  /* 节点注册结构 */

  vlib_node_registration_t *node_registrations;

 

  /* Node index from error code */

  u32 *node_by_error;

} vlib_node_main_t;

 

_vlib_node_registration

typedef struct _vlib_node_registration

{

  /* 此节点的向量处理函数. */

  vlib_node_function_t *function;

 

  /*通过优先级节点函数候选注册 */

  vlib_node_fn_registration_t *node_fn_registrations;

 

  /* 节点名称. */

  char *name;

 

  /* 兄弟名称. */

  char *sibling_of;

 

  /* 节点索引. */

  u32 index;

 

  /* 节点类型. */

  vlib_node_type_t type;

 

  /* 错误字符串. */

  char **error_strings;

 

  /*这个节点的缓冲区格式. */

  format_function_t *format_buffer;

  unformat_function_t *unformat_buffer;

 

  /*这个节点的消息跟踪格式. */

  format_function_t *format_trace;

  unformat_function_t *unformat_trace;

 

  /*用于验证传入帧. */

  u8 *(*validate_frame) (struct vlib_main_t * vm,

                             struct vlib_node_runtime_t *,

                             struct vlib_frame_t * f);

 

  /*每个节点的运行时数据. */

  void *runtime_data;

 

  /*进程堆栈大小. */

  u16 process_log2_n_stack_bytes;

 

  /*每个节点运行时数据的字节数. */

  u8 runtime_data_bytes;

 

  /*输入节点的状态*/

  u8 state;

 

  /* 节点标志. */

  u16 flags;

 

  /* protocol at b->data[b->current_data] upon entry to the dispatch fn */

  u8 protocol_hint;

 

  /*标量和向量的大小(以字节为单位). */

  u16 scalar_size, vector_size;

 

  /*此节点使用的错误代码数量. */

  u16 n_errors;

 

  /*随后的下一个节点名的数目. */

  u16 n_next_nodes;

 

  /* 链表结构,下一个节点*/

  struct _vlib_node_registration *next_registration;

 

  /*此节点输入到的下一个节点的名称. */

  char *next_nodes[];

 

} vlib_node_registration_t;

 

typedef uword (vlib_node_function_t) (struct vlib_main_t * vm,

                                           struct vlib_node_runtime_t * node,

                                           struct vlib_frame_t * frame);

 

vlib_main_or_worker_loop函数中循环处理node调度

你可能感兴趣的:(vpp中的结构体)