3. VPP源码分析(graph node(1))

简介: 2.1. 与结点相关的结构体 2.1.1. 全局结构体 vlib_main_t:每个线程一份,记录着线程使用到的全局数据信息.比如: /* Node graph main structure.

2.1. 与结点相关的结构体

2.1.1. 全局结构体

vlib_main_t:每个线程一份,记录着线程使用到的全局数据信息.
比如:

/* Node graph main structure. */
vlib_node_main_t node_main;

/* Command line interface. */
vlib_cli_main_t cli_main;

/* Packet trace buffer. */
vlib_trace_main_t trace_main;

......

2.1.2. Node相关结构体

vlib_node_t:结点的主结构,包括结点的处理功能函数,名称,结点类型等,主要保存一些相对静态信息
vlib_node_main_t:Node graph相关的全局信息,nodes数组、vlib_next_frame_t、vlib_pending_frame_t等数据
vlib_node_registration_t:注册node结点时使用,保存结点业务逻辑的函数地址,结点类型,结点状态,结点名称等
vlib_node_runtime_t:实际在调度node过程中使用的结构,主要记录在处理过程中的信息变动
vlib_frame_t:每个node都有一个对应的vlib_frame_t,用来保存供node使用的数据集合(标量、矢量)
vlib_next_frame_t:主要是node内部逻辑使用,用于定位该node的下一结点所对应的frame地址
vlib_pending_frame_t:当一个node处理完数据包,则填充该待处理帧管理表数据结,调度框架便能在下一次调度时找到需要接收该数据包的下一个node

2.2. vlib_node_type_t

VLIB_NODE_TYPE_INTERNAL
/* An internal node on the call graph (could be output).
Internal nodes (including output nodes) move data from node to node (or out of the graph for output nodes). */

VLIB_NODE_TYPE_INPUT
/* Nodes which input data into the processing graph.
Input nodes are called for each iteration of main loop. */

VLIB_NODE![1](https://yqfile.alicdn.com/de8130d739704d7c949da6337f99d6d070e55b4f.png)
_TYPE_PRE_INPUT
/* Nodes to be called before all input nodes.
Used, for example, to clean out driver TX rings before processing input. */

VLIB_NODE_TYPE_PROCESS
 /* "Process" nodes which can be suspended and later resumed.
     A lightweight cooperative multi-tasking thread model. Context switching costs a setjmp/longjump pair. */

2.2.1. VLIB_NODE_TYPE_INPUT结点

以dpdk-input结点为例:

2.2.1.1. dpdk burst收包

1
2
DPDK收到的数据包保存在rte_mbuf中,通过rx_vectors按queue_id进行索引。
dpdk_rx_burst将返回收到的包个数n_buffers。

2.2.1.2. 得到to_next指针

3
to_next指针指向下一结点frame的起始vector地址,用于存放数据包的索引值。
4
该宏主要调用以下两个函数:
nf = vlib_node_runtime_get_next_frame(vm, node, next_index);
f = vlib_get_frame(vm, nf->frame_index);
首先,在vlib_node_runtime_t node中的next_frames数组中根据next_index找到下一结点相关的vlib_next_frame_t信息。
找到vlib_next_frame_t后,便可从其中保存的frame_index域找到下一结点对应的vlib_frame_t _f结构体。
并通过计算:
u32 _n = _f->n_vectors;
(to_next) = vlib_frame_vector_args(_f) + _n * sizeof ((to_next)[0]);
返回未使用的vector的起始地址

2.2.1.3. 从DPDK rte_mbuf到vlib_buffer_t

为了方便管理,VPP自定义了vlib_buffer_t类型的缓冲区,其与rte_mbuf的关系如下:
#define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
5
vlib_buffer_t存放在rte_mbuf的headroom中,通过此方法将DPDK与VPP的内存管理机制管理起来

  1. 从xd->rx_vectors得到rte_mbuf指针后,vlib_buffer_from_rte_mbuf再换算成vlib_buffer指针
    6

7

  1. 使用vlib_get_buffer_index函数得到每个vlib_buffer指针相对于buffer_mem_start的offset值
    即作了归一化后的包索引值,将指针值表示成索引值

8
9
这些包索引值将保存在to_next所指向的next_frame中的vector中

2.2.1.4. 验证处理结果

vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0);
当next0 != next_index时,说明该包被正确处理,该宏将do nothing
否则,说明本来该包应去next_index但是发生错误,使得next0 != next_index。该宏会将该错误包索引pi0发往到next0实际的下一个结点

2.2.1.5. vlib_pending_frame_t的添加

完成包处理后下一结点的frame已填充好包索引信息,说明可以进行调度处理需要添加到vlib_pending_frame_t待处理帧管理表中
vlib_put_next_frame(vm, node, next_index, n_left_to_next);
10
主要登记的信息包括:
下一结点frame索引、下一结点runtime_index、下一结点next_frame_index

目录
相关文章
|
11月前
|
JSON 缓存 JavaScript
Node.js躬行记(20)——KOA源码分析(下)
Node.js躬行记(20)——KOA源码分析(下)
|
11月前
|
缓存 JSON JavaScript
Node.js躬行记(19)——KOA源码分析(上)
Node.js躬行记(19)——KOA源码分析(上)
|
网络协议 Unix
源码分析Node的Cluster模块
### 从源码分析Node的Cluster模块 前段时间,公司的洋彬哥老哥遇到一个问题,大概就是本机有个node的http服务器,但是每次请求这个服务器的端口返回的数据都报错,一看返回的数据根本不是http的报文格式,然后经过一番排查发现是另外一个服务器同时监听了http服务器的这个端口。这个时候洋彬老哥就很奇怪,为啥我这个端口明明使用了,却还是可以启动呢?这个时候我根据以前看libuv源码
4637 0
|
网络性能优化 索引 调度
5. VPP源码分析(graph node(3))
2.3. vlib_frame_t 从arguments地址开始的内存空间是vector空间,作为结点接收数据包索引的缓冲区。 2.3.1. vlib_frame_t内存空间 每个线程都会从堆中分配(mmap)一块内存clib_per_cpu_mheapsvm->heap_base = clib_.
6503 0
|
网络性能优化 调度 索引
4. VPP源码分析(graph node(2))
2.2.2. VLIB_NODE_TYPE_PROCESS结点 每个process结点是由jump机制构成的一个协程,协程主要用于等待、处理事件。使用longjmp/setjmp的轻量级多任务协程,由应用进程自行进行调度,不受操作系统调度机制的影响,上下文切换只损耗调用longjmp/setjmp的时间。
7451 1
|
2月前
|
Web App开发 缓存 JavaScript
【安装指南】nodejs下载、安装与配置详细教程
这篇博文详细介绍了 Node.js 的下载、安装与配置过程,为初学者提供了清晰的指南。读者通过该教程可以轻松完成 Node.js 的安装,了解相关配置和基本操作。文章首先介绍了 Node.js 的背景和应用场景,随后详细说明了下载安装包、安装步骤以及配置环境变量的方法。作者用简洁明了的语言,配以步骤图示,使得读者能够轻松跟随教程完成操作。总的来说,这篇文章为初学者提供了一个友好的入门指南,使他们能够顺利开始使用 Node.js 进行开发。
149 1
【安装指南】nodejs下载、安装与配置详细教程
|
2月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
70 0
|
3月前
|
JavaScript 前端开发 API
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)(下)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
34 0
|
3月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)(上)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
42 0