在使用vpp老版本copy报文的时候,经常遇到mbuf泄露的问题,根本原因是在vlib_buffer分段场景下没有将rte_mbuf进行串联,导致dpdk发包时造成了泄漏。最新的版本已经彻底解决了此问题。下面来分析一下:
(资料图片)
首先,先来了解一下dpdk plugins。在plugins目录下除dpdk_plugin.so外,其他模块是不能直接访问dpdk相关函数的,vpp支持dpdk以静态和动态库的方式,具体在dpdk目录下CMakeLists.txt可以看到查询dpdk库。如下:
find_path(DPDK_INCLUDE_DIR PATH_SUFFIXES dpdk NAMES rte_config.h)vpp_plugin_find_library(dpdk DPDK_LIB "libdpdk.a")if (NOT DPDK_INCLUDE_DIR) message(WARNING "-- DPDK headers not found - dpdk plugin disabled") return()endif()if (NOT DPDK_LIB) vpp_plugin_find_library(dpdk DPDK_SHLIB "libdpdk.so") set(DPDK_IS_SHARED_LIB 1) message(WARNING "-- linking dpdk plugin against DPDK shared libs")endif()
可以通过ldd命令确认当前使用静态库还是动态库.没有搜到libdpdk.so,就是使用的静态库方式。
ldd /usr/lib/x86_64-linux-gnu/vpp_plugins/dpdk_plugin.so linux-vdso.so.1 (0x00007ffd901cb000) libnuma.so.1 => /usr/lib/x86_64-linux-gnu/libnuma.so.1 (0x00007fbf050a0000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbf04caf000) /lib64/ld-linux-x86-64.so.2 (0x00007fbf0a3c4000)
vpp其他模块是无法访问到dpdk相关的函数的,是因为vpp启动时以dlopen动态加载的so库,使用需要使用需要dlsym函数负责动态加载符号(函数),第一个参数是句柄(由dlopen时返回的),第二个参数就是给定的函数名称。类似如下:
//链接并打开动态库void *handle = dlopen(dlib_path, RTLD_GLOBAL | RTLD_NOW);//获取add函数//注意:函数指针接收的add函数有几个参数和什么返回类型要一致 CalculatorFuncPointer add_func = dlsym(handle, "add"); int add_ret = add_func(10, 20);
vpp为提供使用dlsym的接口,但是可以使用另外一种方式,就是注册钩子函数来解决。可以参考线程创建的钩子函数:
static vlib_thread_callbacks_t callbacks = { .vlib_launch_thread_cb = &dpdk_launch_thread, .vlib_thread_set_lcore_cb = &dpdk_thread_set_lcore,};static clib_error_t *dpdk_thread_init (vlib_main_t * vm){ vlib_thread_cb_register (vm, &callbacks); return 0;}VLIB_INIT_FUNCTION (dpdk_thread_init);
RteMbuf内存分布图如下:详细请阅读以前文章:vlib ----buffer pool 内存初始化(2)
分段场景下的串联关系如下(两段链表方式):
曾经遇到过使用dpdk来申请报文缓存地址,在ring队列中将rte_mbuf的内存地址写异常的问题,就是通过这种反相推理找到确认被踩的情况。
vpp默认以polling的方式来从dpdk绑定的网卡来收包,具体收包节点在src\plugins\dpdk\device\node.c文件。下面vpp从网卡收包节点的定义及节点函数说明。
VLIB_NODE_FN (dpdk_input_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f){ dpdk_main_t *dm = &dpdk_main; dpdk_device_t *xd; uword n_rx_packets = 0; vnet_device_input_runtime_t *rt = (void *) node->runtime_data; vnet_device_and_queue_t *dq; u32 thread_index = node->thread_index; /*轮询此cpu上的所有设备的输入或者中断。会存在一个cpu绑多个接口的情况 * Poll all devices on this cpu for input/interrupts. */ /* *INDENT-OFF* */ foreach_device_and_queue (dq, rt->devices_and_queues) { xd = vec_elt_at_index(dm->devices, dq->dev_instance); n_rx_packets += dpdk_device_input (vm, dm, xd, node, thread_index, dq->queue_id); } /* *INDENT-ON* */ return n_rx_packets;}/* *dpdk-input节点定义* */VLIB_REGISTER_NODE (dpdk_input_node) = { .type = VLIB_NODE_TYPE_INPUT, .name = "dpdk-input", .sibling_of = "device-input", .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED, /* Will be enabled if/when hardware is detected. */ .state = VLIB_NODE_STATE_DISABLED, .format_buffer = format_ethernet_header_with_length, .format_trace = format_dpdk_rx_trace, .n_errors = DPDK_N_ERROR, .error_strings = dpdk_error_strings,};
在dpdk_device_input函数中调用dpdkpmd收包通用接口从网卡描述符收取报文,具体流程可以参考:DPDK 网卡收包流程。
下面分段报文的处理,需要通过rte_mbuf 串联关系讲vlib_buf也串联起来。
/*通过dpdk pmd接口从网卡收取报文 get up to DPDK_RX_BURST_SZ buffers from PMD */ while (n_rx_packets < DPDK_RX_BURST_SZ) { n = rte_eth_rx_burst (xd->port_id, queue_id, ptd->mbufs + n_rx_packets, DPDK_RX_BURST_SZ - n_rx_packets); n_rx_packets += n; if (n < 32) break; }/*处理从网卡描述符收到的报文。*/static_always_inline uworddpdk_process_rx_burst (vlib_main_t * vm, dpdk_per_thread_data_t * ptd, uword n_rx_packets, int maybe_multiseg, u16 * or_flagsp){....while (n_left) { /*通过rte_mbuf的的搭配vlib-buf头*/ b[0] = vlib_buffer_from_rte_mbuf (mb[0]); /*前64字节赋值模板*/ vlib_buffer_copy_template (b[0], &bt); or_flags |= dpdk_ol_flags_extract (mb, flags, 1); flags += 1; b[0]->current_data = mb[0]->data_off - RTE_PKTMBUF_HEADROOM; n_bytes += b[0]->current_length = mb[0]->data_len; /*多分段的场景,需要通过rte_mbuf 串联关系讲vlib_buf也串联起来*/ if (maybe_multiseg) n_bytes += dpdk_process_subseq_segs (vm, b[0], mb[0], &bt); /*跟踪记录node执行节点trace初始化*/ VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b[0]); /* next */ mb += 1; n_left -= 1; }....}
对应的在plugins目录下dpdk模块文件中src\plugins\dpdk\device\device.c定义dpdk对应的设备类。
/*对应的通用的dpdk tx接口函数*/VNET_DEVICE_CLASS_TX_FN (dpdk_device_class) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * f)/* *dpdk对应的设备类结构体描述* */VNET_DEVICE_CLASS (dpdk_device_class) = { .name = "dpdk", .admin_up_down_function = dpdk_interface_admin_up_down, .subif_add_del_function = dpdk_subif_add_del_function, .rx_redirect_to_node = dpdk_set_interface_next_node, .mac_addr_change_function = dpdk_set_mac_address, .mac_addr_add_del_function = dpdk_add_del_mac_address, .format_flow = format_dpdk_flow, .flow_ops_function = dpdk_flow_ops_fn, .set_rss_queues_function = dpdk_interface_set_rss_queues,};
在对应发包函数中会对分段vlib_buf的连对应的mbuf进行串联,以保证在调用dpdk库中对应网卡的pmd驱动发包接口使用。
/*判断是否存在多段vlib_buf串联场景,将对应的mbuf也串联起来*/ dpdk_validate_rte_mbuf (vm, b[0], 1); /*设置网卡tx 卸载功能*/ dpdk_buffer_tx_offload (xd, b[0], mb[0]);
所以我们其他模块操作分段vlib_buf时,并不需要将考虑将rte_mbufd的进行处理。比如vlib_buffer_copy中只是将vlib-buf头进行也串联。
在项目开发中遇到一个使用vlib_buffer_copy的问题,就是不会赋值current_config_index字段(用于获取当前节点的next0节点)进行复制。会导致报文走到其他的几点上。
在使用vpp过程中,经常遇到rte_mbuf泄露的问题,而了解使用原理对分析问题很有帮助。本文以报文分段场景的处理为背景,学习了报文从哪来(dpdk-input),到哪去(dpdk tx)的实现逻辑。希望本文的介绍对你有所帮助。
标签:
1、花椰菜,又称花菜或椰菜花,是一种十字花科蔬菜,为甘蓝的变种。菜花的头部为白色花序,与西兰花的头...
仓储物流“成渝圈”如何乘势而上? 12月3日,连接昆明和万象的中老铁路全线开通运营,被惠及的显...
两件西周青铜簋时隔三千年成功配对 考古工作者介绍,这个铜簋的盖、身分别时隔40余年出土,纹饰...
“医保砍价”不是一个人在战斗 晁星 “我眼泪都快掉下来了”“每一个小群体都不该被放弃”…...
“购物成瘾”真的是一种病 刘艳 牛雅娟 本周日即将迎来“双十二”促销季,很多人又开始摩拳...
因迷恋山间风景,一男子在甘孜州稻城县海拔4000多米的无人区迷失方向,随后与同伴失联。12月的稻城...
嫌疑人DNA信息比中后,成都市公安局刑侦支队技术处DNA实验室民警白小刚一下坐在凳子上,恍惚迟疑间...
一批反映南京大屠杀历史的新书发布 新华社南京12月7日电(记者邱冰清、蒋芳)“以史为鉴,开创未来...
我在现场·照片背后的故事|电影《亲爱的》里面没有的结局,在我眼前“上映” 12月6日,在深圳市...
冥想?泡脚?不如听听助眠音乐 晚上睡不着,白天睡不醒,成为最贴合都市人群的“睡眠画像”。随...
养老话题 老年教育面临缺口 “终身教育”潜力无限 【现实挑战】“新老年”群体愿意在培养兴...
孙海洋被拐14年儿子如何找到的? 警方侦办另一宗拐骗儿童案时发现线索,通过人像比对、DNA确认找...
北京天文馆、圆明园将对未成年人免费开放 12月6日,北京天文馆发布通知称,12月8日起试行对未成...
今年全国粮食总产量再创新高 连续7年保持在1 3万亿斤以上 根据对全国31个省(区、市)的抽样调...
斑块软的很危险 硬的就无碍? 血管里的“垃圾”分类 赶快学起来! 一项最新研究显示:中国...
诺西那生钠注射液大幅降价 聚焦医保谈判背后脊髓性肌萎缩症家庭 医保目录公布那天 好多家长都...
抖音“窗花剪剪”遭抄袭 被判获赔20万元 法院认为“窗花剪剪”的这种表达方式理应受到《著作权...
公安机关近日侦破3起拐卖儿童案件 失散十几年 3组家庭终于团圆了 北京青年报记者12月6日从公...
2021年度十大网络用语发布 本报讯(记者 路艳霞)作为年度“汉语盘点”活动最具网络特色的组成部...
北京天文馆向未成年人免费开放 本报讯(记者 牛伟坤)北京天文馆对票价免费及优惠政策作出调整:1...
2021北京百个网红打卡地发布 本报讯(记者 李洋)2021北京网红打卡地推荐榜单昨晚正式发布。自然...