VPP概述汇总
一、背景介紹
【鵝廠網(wǎng)事】高性能網(wǎng)關(guān)設(shè)備及服務(wù)實(shí)踐
《高性能網(wǎng)關(guān)設(shè)備及服務(wù)實(shí)踐》這篇博文,介紹了傳統(tǒng)內(nèi)核網(wǎng)絡(luò)協(xié)議棧技術(shù)的瓶頸及怎么突破,從而引入DPDK + VPP這種處理方式。
二、高性能
性能提升方法。
架構(gòu):DPDK使用巨頁(yè)、NUMA、D-cache優(yōu)化,VPP?的I-cache優(yōu)化;
算法:Bihash,查表lockless;
代碼:Vector?、宏構(gòu)造函數(shù)、結(jié)構(gòu)體cacheline對(duì)齊、線程綁核、指令預(yù)取、指令優(yōu)化;
三、轉(zhuǎn)發(fā)流程圖譜
3.1 VPP轉(zhuǎn)發(fā)圖譜
Cisco VPP(5) node關(guān)系圖_趙占旭的博客-CSDN博客_vpp節(jié)點(diǎn)圖
層二轉(zhuǎn)發(fā)圖譜:
層三轉(zhuǎn)發(fā)圖譜:
?
?
3.2 Linux內(nèi)核報(bào)文收發(fā)流程
https://zhaozhanxu.com/2016/07/14/Linux/2016-07-14-Linux-Kernel-Pkts_Processing3/
層二轉(zhuǎn)發(fā):
層三轉(zhuǎn)發(fā):
四、Node節(jié)點(diǎn)及初始化
VPP代碼分析——Node的數(shù)據(jù)結(jié)構(gòu)和初始化_Illina的博客-CSDN博客_node數(shù)據(jù)結(jié)構(gòu)
node的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)如上圖所示,__bootstrap_vlib_main_vector是最頂級(jí)的全局變量,此變量下的vm是一個(gè)vec結(jié)構(gòu),每thread一個(gè)vlib_main_t,對(duì)于node結(jié)構(gòu)來(lái)講,比較重要的是node_main,對(duì)應(yīng)vlib_node_main_t結(jié)構(gòu)體,在vlib_node_main_t中,nodes成員以vec數(shù)據(jù)結(jié)構(gòu)組織,用來(lái)真正保存一個(gè)個(gè)注冊(cè)在VPP系統(tǒng)中的node,vlib_node_t結(jié)構(gòu)中存儲(chǔ)了node節(jié)點(diǎn)的所有信息。
???為查找方便高效,vlib_node_main_t有成員node_by_name,以hash的方式組織,可按name快速hash到node的index;
?? node_registrations是提供給初始化函數(shù)使用的,是一個(gè)單鏈表的結(jié)構(gòu),VLIB_REGISTER_NODE宏注冊(cè)的node在初始化前就預(yù)先掛載在這個(gè)成員變量中。
?
函數(shù)流程如上圖,vlib_unix_main是初始化入口,函數(shù)默認(rèn)會(huì)啟動(dòng)一個(gè)線程,在thread0中完成node結(jié)構(gòu)的注冊(cè)和node graph的創(chuàng)建,vlib_register_all_static_nodes函數(shù)用來(lái)將vlib_node_registration_t結(jié)構(gòu)下node_registrations鏈表中的node真正放到vlib_node_main_t結(jié)構(gòu)下的node池中。
?? vlib_node_main_init函數(shù)用來(lái)根據(jù)注冊(cè)node提供的next node信息,建立一個(gè)完整的node graph,在VPP運(yùn)行正確后,通過(guò)命令show vlib graph可以查看所有注冊(cè)的node和node之間的關(guān)系。
五、Main過(guò)程
VPP源碼分析及流程圖 - ll_1997_ll - 博客園
5.1?vpp/vnet main.c
1.main?首先解析參數(shù),再需要初始化堆,插件的初始化將由他提供。
2.vpe_main_init?初始化各種插件,通過(guò)宏函數(shù)VLIB_INIT_FUNCTION(X),可以通過(guò)遍歷單鏈表、動(dòng)態(tài)鏈接的方式指定不同的初始化類型如早期的配置、功能等
3.調(diào)用?vilb_unix_main
5.2?vilb_unix_mian
vlib_plugin_early_init (vlib_load_one_plugins)?從配置文件中讀取插件的路徑而不用重新編譯.
vlib_thread_stack_init?創(chuàng)建主線程的線程棧,對(duì)于線程的管理,通過(guò)了數(shù)組的形式,所以每次使用地址可以直接通過(guò)偏移量來(lái)找到他
clib_call_jmp?這里執(zhí)行了main線程(thread0)的回調(diào)函數(shù)。
5.3?vlib_main
cli_time_init?用于多線程時(shí)間輪調(diào)度
vlib_register_all_static nodes?同樣也是通過(guò)遍歷單鏈表的方式對(duì)所有的節(jié)點(diǎn)分配內(nèi)存、初始化等等。
vlib_call_all_init_fountions?這里的初始化不同于最開始時(shí)的初始化,這里是建立節(jié)點(diǎn)圖,通過(guò)函數(shù)指針計(jì)算矢量,也就是在節(jié)點(diǎn)圖的下一跳(對(duì)于不同類型的數(shù)據(jù)包所形成的路徑也是不同的)。
vlib_buffer_get_or_create_free_list?創(chuàng)建默認(rèn)的緩沖區(qū),dpdk使用了特定的緩沖區(qū)的格式,vpp在其頭部添加信息使兩者相對(duì)隔離,給網(wǎng)絡(luò)棧和空間存儲(chǔ)提供了便利。
vlib_call_all_config_functions?進(jìn)入主循環(huán)前最后一次進(jìn)行配置
進(jìn)入?vlib_main_loop
5.4?vlib_main_loop
dispatch_process
dispatch_node(PRE_INPUT)?目前只有一個(gè)epoll node,對(duì)socket相關(guān)邏輯提供服務(wù),主要使用在控制業(yè)務(wù)上。可以處理CLI命令以及可以在中斷模式和輪詢模式中切換。
dispatch_node(INPUT)?需要從其他容器中獲得input方法(dpdk_input),由之前構(gòu)建好的節(jié)點(diǎn)圖進(jìn)行矢量跳轉(zhuǎn),
queue_signal_pending?用戶可以自行定義信號(hào)后會(huì)調(diào)用回調(diào)函數(shù)
中斷模式和時(shí)間輪計(jì)算
dispatch_pending_node?由于我們之前已經(jīng)定義好了數(shù)據(jù)包的矢量,現(xiàn)在要做的就是跳轉(zhuǎn)到我收到包后現(xiàn)在要做的事情。(p.s.有對(duì)于trace版本的優(yōu)化以及debug版本顯示更多信息,同時(shí)也可以在gdb中看出數(shù)據(jù)包的流
dispatch_node(INTERNAL)
node->function?調(diào)用節(jié)點(diǎn)指定的動(dòng)作(對(duì)于dpdk來(lái)說(shuō)這里就是發(fā)包)
總結(jié)
- 上一篇: 开源中国软件频道_编程小黑马
- 下一篇: C语言——指针