前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >深入浅出思科VPP24.02系列:内存初始化vlib_physmem_init逻辑介绍

深入浅出思科VPP24.02系列:内存初始化vlib_physmem_init逻辑介绍

作者头像
通信行业搬砖工
发布于 2024-10-14 07:35:23
发布于 2024-10-14 07:35:23
16800
代码可运行
举报
文章被收录于专栏:网络虚拟化网络虚拟化
运行总次数:0
代码可运行

01=上期内容回顾

在往期的内容中,我们介绍了思科VPP软件核心函数vlib_main()函数的业务逻辑介绍,

深入浅出思科VPP24.02系列:vlib_unix_main初始化介绍

深入浅出思科VPP24.02系列:thread0函数业务逻辑介绍

深入浅出思科VPP24.02系列:vlib_main函数业务逻辑介绍

本期我们将继续深入浅出思科vpp24.02系列专题,介绍VPP初始化phymems初始化的函数的业务逻辑介绍。

02=vlib_physmem_init函数介绍

在往期的内容中,我们介绍了思科VPP软件对内存空间初始化的函数vlib_physmem_init()的业务逻辑介绍,其在vlib_main()中备调用的。

其逻辑如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
clib_error_t *
vlib_physmem_init (vlib_main_t * vm)
{
  vlib_physmem_main_t *vpm = &vm->physmem_main;
  clib_error_t *error = 0;
  u64 *pt = 0;
  void *p;

  /* check if pagemap is accessible */
  pt = clib_mem_vm_get_paddr (&pt, min_log2 (sysconf (_SC_PAGESIZE)), 1);
  if (pt && pt[0])
    vpm->flags |= VLIB_PHYSMEM_MAIN_F_HAVE_PAGEMAP;
  vec_free (pt);

#ifdef __linux__
  if ((error = linux_vfio_init (vm)))
    return error;
#endif /* __linux__ */

  p = clib_mem_alloc_aligned (sizeof (clib_pmalloc_main_t),
            CLIB_CACHE_LINE_BYTES);
  memset (p, 0, sizeof (clib_pmalloc_main_t));
  vpm->pmalloc_main = (clib_pmalloc_main_t *) p;

  if (vpm->base_addr == 0)
    vpm->base_addr = VLIB_PHYSMEM_DEFAULT_BASE_ADDDR;

  clib_pmalloc_init (vpm->pmalloc_main, vpm->base_addr, vpm->max_size);

  /* update base_addr and max_size per actual allocation */
  vpm->base_addr = (uword) vpm->pmalloc_main->base;
  vpm->max_size = (uword) vpm->pmalloc_main->max_pages <<
    vpm->pmalloc_main->def_log2_page_sz;

  return error;
}

函数声明:clib_error_t *vlib_physmem_init (vlib_main_t * vm)

返回值:函数返回一个指向 clib_error_t 类型的指针,如果初始化成功,返回NULL(或0),表示没有错误;如果失败,返回一个错误信息的指针。

03=函数工程意义分析

1、变量声明:指向物理内存管理主结构体的指针。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vlib_physmem_main_t *vpm = &vm->physmem_main;
typedef struct
{
  u32 flags;
  uword base_addr;
  uword max_size;
#define VLIB_PHYSMEM_MAIN_F_HAVE_PAGEMAP  (1 << 0)
#define VLIB_PHYSMEM_MAIN_F_HAVE_IOMMU    (1 << 1)
  vlib_physmem_map_t *maps;
  clib_pmalloc_main_t *pmalloc_main;
} vlib_physmem_main_t;

2、检测页表可访问性

使用 clib_mem_vm_get_paddr 函数尝试获取页表地址,通过open函数打开虚拟文件系统proc下的路径(/proc/self/pagemap)获取pagemap的关系,如果成功且页表非空,则设置 vpm 的标志位 VLIB_PHYSMEM_MAIN_F_HAVE_PAGEMAP,表示有页表可用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  /* check if pagemap is accessible */
  pt = clib_mem_vm_get_paddr (&pt, min_log2 (sysconf (_SC_PAGESIZE)), 1);
  if (pt && pt[0])
    vpm->flags |= VLIB_PHYSMEM_MAIN_F_HAVE_PAGEMAP;
  vec_free (pt);

那么DPDK/VPP中区别传统linux,为什么需要大页呢?

答:在DPDK中,页表大页(Huge Pages for Mbuf Pools)是为了提高内存的效率和性能,通过将内存区域映射到大型页面上减少内存碎片,从而使得DPDK的内存池能够更高效地管理内存。

3、Linux VFIO 初始化:

如果代码在Linux系统上编译和运行,尝试初始化VFIO(Virtual Function I/O),这是Linux内核的一个框架,允许用户空间程序直接管理硬件设备。如果初始化失败,则返回错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifdef __linux__
  if ((error = linux_vfio_init (vm)))
    return error;
#endif /* __linux__ */

4、分配并初始化物理内存分配器:

使用 clib_mem_alloc_aligned 函数分配一块对齐到缓存行大小的内存,用于物理内存分配器 clib_pmalloc_main_t

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  p = clib_mem_alloc_aligned (sizeof (clib_pmalloc_main_t),
            CLIB_CACHE_LINE_BYTES);
  memset (p, 0, sizeof (clib_pmalloc_main_t));

将分配的内存清零,并设置为 vpm->pmalloc_main

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 vpm->pmalloc_main = (clib_pmalloc_main_t *) p;

5、设置物理内存基地址和最大max_size数值大小:

如果 vpm->base_addr 为0,则将其设置为默认值 VLIB_PHYSMEM_DEFAULT_BASE_ADDDR。

调用 clib_pmalloc_init 函数初始化物理内存分配器,传入基地址和最大大小。

更新 vpm->base_addrvpm->max_size,根据实际的物理内存分配器初始化结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  if (vpm->base_addr == 0)
    vpm->base_addr = VLIB_PHYSMEM_DEFAULT_BASE_ADDDR;

  clib_pmalloc_init (vpm->pmalloc_main, vpm->base_addr, vpm->max_size);

  /* update base_addr and max_size per actual allocation */
  vpm->base_addr = (uword) vpm->pmalloc_main->base;
  vpm->max_size = (uword) vpm->pmalloc_main->max_pages <<
    vpm->pmalloc_main->def_log2_page_sz;

6、向上一级调用函数 vlib_main()返回类型为clib_error_t的返回值。

04=读取phymems参数的方法

1、该部分通过命令行show physmem [verbose | detail | map]读取vpm->pmalloc_main显示上述初始化配置的参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static clib_error_t *
show_physmem (vlib_main_t * vm,
        unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vlib_physmem_main_t *vpm = &vm->physmem_main;
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 verbose = 0, map = 0;

  if (unformat_user (input, unformat_line_input, line_input))
    {
      while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
  {
    if (unformat (line_input, "verbose"))
      verbose = 1;
    else if (unformat (line_input, "v"))
      verbose = 1;
    else if (unformat (line_input, "detail"))
      verbose = 2;
    else if (unformat (line_input, "d"))
      verbose = 2;
    else if (unformat (line_input, "map"))
      map = 1;
    else
      break;
  }
      unformat_free (line_input);
    }

  if (map)
    vlib_cli_output (vm, " %U", format_pmalloc_map, vpm->pmalloc_main);
  else
    vlib_cli_output (vm, " %U", format_pmalloc, vpm->pmalloc_main, verbose);

  return 0;
}

VLIB_CLI_COMMAND (show_physmem_command, static) = {
  .path = "show physmem",
  .short_help = "show physmem [verbose | detail | map]",
  .function = show_physmem,
};

05=本次内容总结

本次内容主要是介绍了VPP中对于底层硬件大页相关的初始化操作的介绍,其思维导图可以总结为:

总的来说,本次介绍的vlib_physmem_init函数的目的是初始化VPP库中的物理内存管理模块,包括检查页表可访问性、在Linux上初始化VFIO(如果适用)、分配并初始化物理内存分配器,并设置物理内存的基地址和最大大小。函数show_physmem是对配置进行读取显示的功能。本次介绍就到此为止。小伙伴们,你们学会了吗?

作者简介

作者:通信行业搬砖工

前深圳某大型通信设备厂商从业人员

前H3Com骨干网核心交换路由器人员

前某全球500强通信公司通信砖家

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

本文分享自 通信行业搬砖工 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入浅出思科VPP24.02系列:buffer模块vlib_buffer_main_init逻辑介绍-Part I
在往期的内容中,我们介绍了思科VPP软件初始化内存的核心函数vlib_stats_init()函数的业务逻辑介绍,
通信行业搬砖工
2024/10/25
2840
深入浅出思科VPP24.02系列:buffer模块vlib_buffer_main_init逻辑介绍-Part I
深入浅出思科VPP24.02系列:vlib_main函数业务逻辑介绍
本期我们将继续深入浅出思科vpp24.02系列专题,介绍VPP核心业务vlib_main函数的业务逻辑介绍。
通信行业搬砖工
2024/10/14
2060
深入浅出思科VPP24.02系列:vlib_main函数业务逻辑介绍
深入浅出思科VPP24.02系列:thread0函数业务逻辑介绍
在上一篇章节中,我们介绍了思科VPP软件核心函数vlib_unix_main初始化介绍,
通信行业搬砖工
2024/10/12
1160
深入浅出思科VPP24.02系列:thread0函数业务逻辑介绍
深入浅出思科VPP24.02系列:日志模块vlib_log_init逻辑介绍
本期我们将继续深入浅出思科vpp24.02系列专题,介绍VPP的日志log功能初始化的函数的业务逻辑介绍。
通信行业搬砖工
2024/10/21
2230
深入浅出思科VPP24.02系列:日志模块vlib_log_init逻辑介绍
深入浅出思科VPP24.02系列:vlib_unix_main初始化介绍
本文章我们将要进行思科VPP(Vector Packet Processing)软件架构初始化流程中设计的核心函数vlib_unix_main初始化介绍,其初始化流程如下所示。
通信行业搬砖工
2024/10/10
1480
深入浅出思科VPP24.02系列:vlib_unix_main初始化介绍
深入浅出思科VPP24.02系列:统计模块vlib_stats_init逻辑介绍
在往期的内容中,我们介绍了思科VPP软件初始化内存的核心函数vlib_log_init()函数的业务逻辑介绍,
通信行业搬砖工
2024/10/25
1510
深入浅出思科VPP24.02系列:统计模块vlib_stats_init逻辑介绍
走进vpp物理内存管理的世界(1)
这篇文章标题已经写很久了,最近时间一直忙工作上事情,搁浅了很长一段时间。每次阅读到vpp对物理内存的管理这块都会绕过。终于鼓起勇气要来阅读一番。自己的理解也比较狭隘,比如通过/proc/pid/pagemap将虚拟地址查询到物理地址,本人也没有完全理解(参照其他人博客)。欢迎大家指正和交流。
dpdk-vpp源码解读
2023/03/07
1.5K0
走进vpp物理内存管理的世界(1)
Ubuntu系统运行VPP24.02系列:main函数初始化介绍
1、VPP Infra ( VPP infrastructure layer 基础结构层)
通信行业搬砖工
2024/06/13
2560
Ubuntu系统运行VPP24.02系列:main函数初始化介绍
vlib ----buffer pool 内存初始化(1)
目前阅读最新的vpp(20-1)代码,报文存储区域rte_mbuf已经不再通过DPDK结构来申请了,目前是在vpp自己管理的物理内存上直接申请而来。下面就简单了解下buffer创建的过程。
dpdk-vpp源码解读
2023/03/07
7580
vlib ----buffer pool 内存初始化(1)
思科VPP系列砖题三:VPP节点注册
本章节将要介绍VPP node的注册机制,在介绍VPP的node机制之前,我们首先介绍一下VPP的软件架构核和设计思想。
通信行业搬砖工
2023/03/30
1.2K0
思科VPP系列砖题三:VPP节点注册
learning:vpp unix cli 处理流程1
这里需要了解vpp启动过程中存在初始化宏函数的执行顺序。当前unix cli相关资源的使用就依赖这个顺序来保证的。下面先来了解一下:
dpdk-vpp源码解读
2023/03/07
1.3K0
learning:vpp unix cli 处理流程1
vlib ----buffer pool 内存初始化(2)
vpp注册字节mempool 操作函数,后续创建mempool时,会通过name=“vpp”,索引到mempool ops的索引,设置操作入队与出队的操作接口。所以这里并不会使用dpdk的ring队列(应该是从vpp-19.04版本伴随着dpdk增加了ops操作接口后,修改成这样的。)
dpdk-vpp源码解读
2023/03/07
1.2K0
vlib ----buffer pool 内存初始化(2)
learning vpp:内存管理和 DPDK API
本译文源自PANTHEON.tech公司技术博客文章《VPP 105: Memory Management & DPDK APIs》,在我们深入运用VPP的过程中,不免对其中涉及的各类技术与库——它们的实践应用、优势特性及对应API——产生诸多疑问。这篇针对性的文章恰好为我们详尽答疑,扫清困惑。很适合入门vpp的同学学习。如需查阅原文,欢迎直接点击文末阅读原文。
dpdk-vpp源码解读
2024/04/15
8340
learning vpp:内存管理和 DPDK API
vppinfra--- file.h: unix file handling
file 提供了一套unix文件描述符操作管理接口。用于管理所有Linux文件操作和socket通信。并提供了相关的注册、更新、删除的api接口。
dpdk-vpp源码解读
2023/03/07
5380
vppinfra---  file.h: unix file handling
探究分段场景下vlib_buf在收发包的处理
在使用vpp老版本copy报文的时候,经常遇到mbuf泄露的问题,根本原因是在vlib_buffer分段场景下没有将rte_mbuf进行串联,导致dpdk发包时造成了泄漏。最新的版本已经彻底解决了此问题。下面来分析一下:
dpdk-vpp源码解读
2023/03/07
2.6K3
探究分段场景下vlib_buf在收发包的处理
思科VPP系列砖题二:VPP启动流程分析
有关于如何编译vpp,本章节不做过多的讲述,下面我们主要分析一下VPP这款软件架构的启动流程;
通信行业搬砖工
2023/03/30
1.2K0
思科VPP系列砖题二:VPP启动流程分析
vpp IPsec with DPDK Cryptodev have buffer resource leak.
此刻是否已经准备下班或者已经在下班的路上,首先提前祝大家五一快乐,北京疫情正处于关键阶段,各位出行注意防护。
dpdk-vpp源码解读
2023/01/04
1.3K0
vpp IPsec with DPDK Cryptodev have  buffer resource leak.
vpp plugins插件相关介绍
前面文章有介绍过通过make-plugin.sh命令行自动生成plugins的架构,vpp 软件架构介绍;本文就来讲解一下plugins插件的加载和使用流程。
dpdk-vpp源码解读
2023/03/07
2K0
vpp plugins插件相关介绍
Vpp QoS Hierarchical Scheduler(2)
上篇讲解了Hqos基本知识点及vpp Hqos配置及基本流程框架,今天通过源码来分析Hqos实现逻辑。
dpdk-vpp源码解读
2023/03/07
1.4K0
Vpp QoS Hierarchical Scheduler(2)
Vpp --node节点调度总结
Vpp的功能逻辑被划分为多个featuce arc(比如ipv4、IPv6、l2、MPLS等),每个feature arc是由一定顺序的node组成,每个node完成一个功能。本文主要是来介绍一下node的类型及调度模式。
dpdk-vpp源码解读
2023/03/07
2.3K0
Vpp --node节点调度总结
推荐阅读
相关推荐
深入浅出思科VPP24.02系列:buffer模块vlib_buffer_main_init逻辑介绍-Part I
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验