前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >learning:buffer metadata tracking

learning:buffer metadata tracking

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

简介

vpp官方文档中有buffer mdata相关介绍,公众号也进行了简单的翻译:vpp Buffer Metadata,本文主要介绍一下源码中mdata插件的使用(主要用来跟踪buffer mdata的变化)。代码比较简单,但是实现框架值得我们来详细了解一下。

官方链接:https://fd.io/docs/vpp/master/gettingstarted/developers/metadata.html 。 最近在vpp交流群中有群友遇到buffer重复释放的问题,我觉得也可以借助此框架来检测buffer使用不当问题,应该可以确认到那个node节点的故障。曾经遇到过一次dpdk mbuf ring队列地址被踩的问题,思路和这个框架差不多。https://blog.csdn.net/sjin_1314/article/details/106090582?spm=1001.2014.3001.5501

相关命令行

1、开启/关闭buffer mdata tracking

代码语言:javascript
复制
buffer metadata tracking [on][off]

2、查询buffer mdata的变化 buffer mdata 主要是跟踪当前节点在调用node->function函数前后vlib_buffer_t结构中前128字节的中数据是否存在变化。

代码语言:javascript
复制
learning_vpp# show buffer metadata 

ip4-icmp-echo-request: flags 
  vnet_buffer_t: sw_if_index[0] #表示当前节点src接口发生了变化。
  vnet_buffer2_t: no changes

arp-reply: current_data current_length current_config_index punt_reason 
  vnet_buffer_t: sw_if_index[1] 
  vnet_buffer2_t: no changes
arp-input: current_config_index punt_reason 
  vnet_buffer_t: feature_arc_index 
  vnet_buffer2_t: no changes
ip4-glean: error 
  vnet_buffer_t: no changes
  vnet_buffer2_t: no changes
ip6-input: current_config_index punt_reason 
  vnet_buffer_t: feature_arc_index ip.adj_index[0] l2.feature_bitmap map.mtu map_t.map_domain_index cop.current_config_index lisp.overlay_afi tcp.connection_index snat.flags 
  vnet_buffer2_t: no changes

perf callback框架

vpp底层基础库文件callback_data.h中提供callback函数初始化、添加、删除、查询等一系列的操作函数。 下面以buffer mdata使能为例介绍。

代码语言:javascript
复制
#1、使用clib_callback_data_typedef来定义callback集合的结构体
clib_callback_data_typedef (vlib_node_runtime_perf_callback_set_t,
            vlib_node_runtime_perf_callback_data_t);
#2、perf callbacks定义在viib_main_t结构中
typedef struct vlib_main_t
{
   vlib_node_runtime_perf_callback_set_t vlib_node_runtime_perf_callbacks;
}
3、声明callback 回调函数
typedef void (*vlib_node_runtime_perf_callback_fp_t)
  (struct vlib_node_runtime_perf_callback_data_t * data,
   vlib_node_runtime_perf_callback_args_t * args);

vlib_node_runtime_perf_callbacks 变量定义在vlib_main_t结构中,说明每个worker核都存储一份了,在使能的时候,需要每个worker线程都需要使能。

相关结构体之间关系如下图所示:

callback函数应该是提供了一种线程安全接口,在vlib_node_runtime_perf_callback_set_t 结构体中有三个指针 curr、(volatile) next,spare 及互斥锁来实现线程安全接口。不过当前buffer mdata本身就是线程安全的。

buffer mdata注册回调函数
代码语言:javascript
复制
int
mdata_enable_disable (mdata_main_t * mmp, int enable_disable)
{
  int rv = 0;
  vlib_thread_main_t *thread_main = vlib_get_thread_main ();
  int i;
  /*多核模式下需要申请modify_lock互斥锁资源*/
  if (mmp->modify_lock == 0 && thread_main->n_vlib_mains > 1)
  {
     clib_spinlock_init (&mmp->modify_lock);
  }
  /*首次时,需要申请资源*/
  if (vec_len (mmp->before_per_thread) == 0)
 {
      mdata_none.node_index = ~0;
      vec_validate (mmp->before_per_thread, vlib_get_n_threads () - 1);
 }

  /*重置节点函数*/
  vec_reset_length (mmp->modifies);
  /*每个线程都需要使能mdata trace callback函数*/
  for (i = 0; i < vlib_get_n_threads (); i++)
  {
      vlib_main_t *ovm = vlib_get_main_by_index (i);
      if (ovm == 0)
        continue;

      clib_callback_data_enable_disable (
    &ovm->vlib_node_runtime_perf_callbacks, mdata_trace_callback,
    enable_disable);
 }

  return rv;
}
以dispatch node为例调度

以dispatch_node vpp调度函数为例,介绍perf callback执行框架,大概逻辑就是三步: 1、执行node节点函数前,保存buffer mdata元数据 2、执行node函数处理 3、执行node函数处理后,对比前后buffer mdata元数据的变化。

代码语言:javascript
复制
static_always_inline u64
dispatch_node (xxxxx)
{
  /*1.执行调度前,保存buffer mdata元数据*/
  vlib_node_runtime_perf_counter (vm, node, frame, 0, last_time_stamp, 
         VLIB_NODE_RUNTIME_PERF_BEFORE);
   /*2、node 函数处理*/
   n = node->function (vm, node, frame);

  /*3、执行函数处理后,执行buffer mdata元数据对比,是否存在变化*/
  vlib_node_runtime_perf_counter (vm, node, frame, n, t,
          VLIB_NODE_RUNTIME_PERF_AFTER);
}

个人觉得可以利用此框架实现一些check动作,比如在开头说明dpdk mbuf ring队列地址被踩的问题时,就是在node-》function函数前后检查ring队列中mbuf地址是否存在异常。

mdata插件

mdata功能一共就三个文件api,.c,.h文件,功能相对比较简单。这里就不介绍了,感兴趣的自己阅读一下代码。下面主要说一下结构体:

说明: before_per_thread[thread_index][vec_header]:二级指针,一级以线程id,二级是vector结构头指针。用来保存node节点在调用node函数前存储buffer mdata元数据。 modifies[node_index]:记录元数据变化,0:表示没有变化,1:表示有变化。

总结

本文简单的介绍一下vpp mdata插件的功能及perf callback的框架,个人觉得此框架还是能做很多东西的,比如存储报文经过那些node节点以及buffer泄露检查动作,可以做成动态使能。

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

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

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

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

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