前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vpp buffer 泄露问题定位思路

vpp buffer 泄露问题定位思路

作者头像
dpdk-vpp源码解读
发布2023-03-07 17:14:55
5260
发布2023-03-07 17:14:55
举报
文章被收录于专栏:DPDK VPP源码分析DPDK VPP源码分析

前面我们简单了解了buffer相关初始化及内存分布情况,这篇文章来讲一下我目前遇到过buffer相关的一些问题及定位手段。没有阅读过前面2节内容的,需要先熟悉一下,链接如下:

vlib ----buffer pool 内存初始化(1)

vlib ----buffer pool 内存初始化(2)

buffer泄露问题确认:

我们可以通过下面的命令行来查询buffer使用情况:

代码语言:javascript
复制
DBGvpp# show buffers
Pool Name            Index NUMA  Size  Data Size  Total  Avail  Cached   Used
default-numa-0         0     0   2496     2048   430185 424425    919    4841

当Used使用数量持续增加而不减少时,可能就存在buffer泄露了。

在vpp老的版本中可能需要查询dpdk buffer情况(老版本buffer还是由dpdk来申请)

代码语言:javascript
复制
DBGvpp# show dpdk buffer
name="vpp pool 0"  available =     694 allocated =  429491 total =  430185

注意:在新版本中上面命令行是无效的。

buffer泄露问题如何定位:

其实vpp源码中提供了一种方法,就是跟踪报文所走的node节点。默认是关闭的,需要自己打开。 宏定义在文件src\vlib\buffer.h中。

代码语言:javascript
复制
#define VLIB_BUFFER_TRACE_TRAJECTORY 0
#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
extern void (*vlib_buffer_trace_trajectory_cb) (vlib_buffer_t * b, u32 index);
extern void (*vlib_buffer_trace_trajectory_init_cb) (vlib_buffer_t * b);
extern void vlib_buffer_trace_trajectory_init (vlib_buffer_t * b);
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) \
  vlib_buffer_trace_trajectory_init (b);
#else
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */

node节点的信息存储在私有字段2中,指针:trajectory_trace,文件src\vnet\buffer.h

代码语言:javascript
复制
typedef struct
{
  .......
  union
  {
    struct
    {
#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
      /* buffer trajectory tracing */
      u16 *trajectory_trace;
#endif
    };
 ..........
  };
} vnet_buffer_opaque2_t;

在代码中没有找到能打印trajectory_trace的地方,可能只能借助gdb了吧。 但是使用中可能存在问题,我们可以看一下vlib_buffer_copy函数中是一段代码如下:

代码语言:javascript
复制
clib_memcpy_fast (d->opaque2, s->opaque2, sizeof (s->opaque2));

默认情况下是是一个buffer对应一个trajectory_trace内存,在copy或者clone函数都是直接复制的,就会导致转发过程中判断异常。目前没有找到好的方法修改,我们借鉴其的方法利用buffer结构中pre-data字段来存储node索引。下面是我修改后的patch文件。

代码语言:javascript
复制
diff --git a/src/vlib/buffer.h b/src/vlib/buffer.h
index 42e3cdf98..472d3c27f 100755
--- a/src/vlib/buffer.h
+++ b/src/vlib/buffer.h
@@ -487,6 +487,8 @@ extern void (*vlib_buffer_trace_trajectory_init_cb) (vlib_buffer_t * b);
 extern void vlib_buffer_trace_trajectory_init (vlib_buffer_t * b);
 #define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) \
   vlib_buffer_trace_trajectory_init (b);
+#elif CLIB_DEBUG > 0
+#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) ((b)->pre_data[0] = 0)
 #else
 #define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
 #endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
diff --git a/src/vlib/main.c b/src/vlib/main.c
old mode 100644
new mode 100755
index 90ce53de5..c6e738eaf
--- a/src/vlib/main.c
+++ b/src/vlib/main.c
@@ -1198,6 +1198,26 @@ dispatch_node (vlib_main_t * vm,
        dispatch_pcap_trace (vm, node, frame);
       n = node->function (vm, node, frame);
     }
+  #if CLIB_DEBUG > 0
+  else if ((CLIB_DEBUG > 0) &&  frame)
+  {
+        int i;
+        u32 *from;
+        from = vlib_frame_vector_args (frame);
+        for (i = 0; i < frame->n_vectors; i++)
+        {
+            vlib_buffer_t *b = vlib_get_buffer (vm, from[i]);
+            b->pre_data[0]++;
+            if (b->pre_data[0] < 32)
+            {
+                b->pre_data[b->pre_data[0]] = (u8)node->node_index;
+            }
+        }
+        if (PREDICT_FALSE (vm->dispatch_pcap_enable))
+            dispatch_pcap_trace (vm, node, frame);
+        n = node->function (vm, node, frame);
+  }
+  #endif
   else
     {
       if (PREDICT_FALSE (vm->dispatch_pcap_enable))

如果存在buffer泄露,我们可以大致根据在buffer池中找到buffer索引,多查询几个索引的node路径,能大致确认是那个接口处理存在的问题。再去详细阅读代码。

总结:

本文只是详细介绍了定位buffer泄露问题的思路,当然具体问题还需要具体分析。通过一些手段来缩小排查范围。如果大家由更好的思路或者方法,欢迎交流。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DPDK VPP源码分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • buffer泄露问题确认:
  • buffer泄露问题如何定位:
  • 总结:
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档