在使用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从网卡收包节点的定义及节点函数说明。
Copyright 2015-2022 财务报告网版权所有 备案号: 京ICP备12018864号-19 联系邮箱:29 13 23 6 @qq.com