前言

基于 dpdk-16.04 开发的 dpdk 程序需要使用的大页内存总大小可以通过计算得出,但由于 dpdk-16.04 legacy memory 模型只支持物理地址连续的 segment 内存分配方式,在系统启动后再动态设置大页时,物理地址相对离散,则没有较大的 memseg 来分配。

这样如果要分配一块非常大的空间,尽管小于总的大页内存空间,仍有可能因为最大的 memseg 大小不足而分配失败。

为了解决这个问题,大页的预留方式可以修改为通过内核启动参数配置预留。这种方式只能让大页内存的物理地址相较系统启动后分配相对集中,但常常还是需要分配更多的大页来增大单个 segment 能够分配的最大空间。

而当大页内存预留后其它程序能够使用的内存空间减少,大页的数量分配不合理就会造成内存浪费。如果有一种方式能够在运行时观测 dpdk 内部大页的使用情况,并找到最大的 memseg 空间,也许就可以适当减少大页的数量,为其它进程留出更多的内存、使用更少的内存条。

如何在 dpdk 程序运行时获取大页使用情况?

在 lib/librte_eal/common/malloc_heap.c 文件中有如下函数:

int
malloc_heap_get_stats(const struct malloc_heap *heap,struct rte_malloc_socket_stats *socket_stats)
{size_t idx;struct malloc_elem *elem;/* Initialise variables for heap */socket_stats->free_count = 0;socket_stats->heap_freesz_bytes = 0;socket_stats->greatest_free_size = 0;/* Iterate through free list */for (idx = 0; idx < RTE_HEAP_NUM_FREELISTS; idx++) {for (elem = LIST_FIRST(&heap->free_head[idx]);!!elem; elem = LIST_NEXT(elem, free_list)){socket_stats->free_count++;socket_stats->heap_freesz_bytes += elem->size;if (elem->size > socket_stats->greatest_free_size)socket_stats->greatest_free_size = elem->size;}}/* Get stats on overall heap and allocated memory on this heap */socket_stats->heap_totalsz_bytes = heap->total_size;socket_stats->heap_allocsz_bytes = (socket_stats->heap_totalsz_bytes -socket_stats->heap_freesz_bytes);socket_stats->alloc_count = heap->alloc_count;return 0;
}

此函数遍历指定的 malloc_heap 上的 free_list 来 dump 空闲空间及最大可分配的空间,可以在外部程序中调用此函数来 dump 信息。dpdk 中每一个 numa 节点的大页内存都会分配一个 malloc_heap 结构,此结构保存在 rte_config 共享内存中,可以获取到 rte_config 的内容,遍历每一个 malloc_heap 结构,调用 malloc_heap_get_stats 来获取大页的使用数据。

测试方法

修改 l2fwd 程序源码,在 dpdk rte_eal_init 初始化后执行 pause 暂停。同时修改 proc_info 代码,在调用 mem_display 前按照上文描述的方法调用 malloc_heap_get_stats 函数 dump 信息。

先运行 l2fwd 程序,然后运行 proc_info 程序观测大页内存内部使用情况。

测试记录

在系统开机后设置 49 个 2M 大页(都在 numa 0 上),当 l2fwd 运行后,添加 -m 参数运行 proc_info 程序,终端输出信息部分摘录如下:

numa 0 biggest_free_size is 6291392
numa 0 total_len is 102757824 byte, free_size is 100086528 byte
numa 0 total_len is 97m, free_size is 95m
----------- MEMORY_SEGMENTS -----------
Segment 0: phys:0x71c00000, len:2097152, virt:0x7fec3e000000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 1: phys:0x74400000, len:4194304, virt:0x7fec3da00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 2: phys:0x75000000, len:2097152, virt:0x7fec3d600000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 3: phys:0x75800000, len:2097152, virt:0x7fec3d200000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 4: phys:0x75c00000, len:4194304, virt:0x7fec3cc00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 5: phys:0x76400000, len:2097152, virt:0x7fec3c800000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 6: phys:0x76e00000, len:2097152, virt:0x7fec3c400000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 7: phys:0x77400000, len:2097152, virt:0x7fec3c000000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 8: phys:0x77e00000, len:2097152, virt:0x7fec3bc00000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 9: phys:0x78c00000, len:4194304, virt:0x7fec3b600000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 10: phys:0x79400000, len:4194304, virt:0x7fec3b000000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
Segment 11: phys:0x79a00000, len:6291456, virt:0x7fec3a800000, socket_id:0, hugepage_sz:2097152, nchannel:0, nrank:0
....................................................................................................................

最大的 free 空间为 6291392(内部数据占了一部分空间,故而小于 6291456),尽管总共有 98M 大页内存能够使用,但由于单次分配的内存必须物理空间连续(位于一个 segment),则最大分配 6291392(5.9M) 空间,说明此时物理内存已经非常离散。

总结

dpdk legacy 内存模型实现有些简陋,按照一般的思路,总的内存足够应该就能够分配出需要的空间,然而在 dpdk legacy 内存模型下却会受限于单块连续物理内存的最大值,使用内核启动参数预留内存算是一种规避方法,最好还是更新 dpdk 版本,新的内存模型已经解决了这一问题。

如何在程序运行时获取 dpdk-16.04 大页使用情况?相关推荐

  1. 【解决】Python程序运行时所占内存越来越大

    1.问题描述 最近在用Python(Pyqt5)编写一个可以获取gpu信息(功耗.显存占用.利用率等)并将这些信息保存成csv文件的程序.在程序编写完成后,运行时却发现,随着程序的运行,所占用的内存每 ...

  2. java 程序运行时注入方法_Spring入门(九):运行时值注入

    Spring提供了2种方式在运行时注入值: 属性占位符(Property placeholder) Spring表达式语言(SpEL) 1. 属性占位符 1.1 注入外部的值 1.1.1 使用Envi ...

  3. error C2057: expected constant expression (C语言中数组的大小可以在程序运行时定义吗? )

    数组的大小可以在程序运行时定义吗? 不.在数组的定义中,数组的大小必须是编译时可知的,不能是在程序运行时才可知的.例如,假设i是一个变量,你就不能用i去定义一个数组的大小: char array[i] ...

  4. Delphi-TScreen表示应用程序运行时屏幕的状态

    TScreen表示应用程序运行时屏幕的状态. 类关系 TObject->TPersistent->TComponent TScreen引进具有表示下列各种情况的属性 什么窗体和数据模块已经 ...

  5. gettype获取类名_在TypeScript中运行时获取对象的类名

    在TypeScript中运行时获取对象的类名 是否可以使用typescript在运行时获取对象的类/类型名称? class MyClass{} var instance = new MyClass() ...

  6. springboot_通过Actuator了解应用程序运行时的内部状况

    Actuator 的端点 Spring Boot Actuator的关键特性是在应用程序里提供众多Web端点,可以分为三大类:配置端点.度量端点和其他端点.通过它们了解应用程序运行时的内部状况.有了A ...

  7. java hibernate方言_java – 如何在运行时获取Hibernate方言

    在我的应用程序中,我使用Hibernate与SQL Server数据库,所以我设置 在我的persistence.xml中. 在某些情况下,我想用NULL包括排序记录,我使用关键字NULLS FIRS ...

  8. java 获取运行时参数,Java8增强反射可以在运行时获取参数名

    技术公众号:Java In Mind(Java_In_Mind),欢迎关注! 原文:Java8增强反射可以在运行时获取参数名 介绍 在JDK增强意见:JPE 118:Access to Paramet ...

  9. C语言编程练习 2.编写人得票统计程序。设有3个候选人,每次输入一个得票候选人的名字,不考虑弃权情况,要求最后输出各个候选人的得票结果(参加投票人数由程序运行时输入)。

    题目完整描述 编写人得票统计程序.设有3个候选人,每次输入一个得票候选人的名字,不考虑弃权情况,要求最后输出各个候选人的得票结果(参加投票人数由程序运行时输入). 这是一道关于 一维数组做函数参数 的 ...

最新文章

  1. 【洛谷P1816 忠诚】线段树
  2. ubuntu16.4中创建帐户
  3. 常见架构TLB miss处理方法(转)
  4. Fiddler抓取https相关设置
  5. 219. 单页应用 会话管理(session、cookie、jwt)
  6. 这个 HTTP 实战项目,帮你理清 Go 网络编程的底层逻辑
  7. 微信填写服务器配置 php操作方法
  8. WCF系统内置绑定列表与系统绑定所支持的功能
  9. 利用百度地图API,在浏览器中找到自己的位置
  10. win10系统如何查询本机的IP地址和外网IP地址
  11. Linux(CentOS7)中如何安装QQ
  12. 转:性、恐惧、爱、信念,管理者一生都逃不掉的课题
  13. Windows快捷键小记
  14. 键盘记录工具(支持中文)
  15. 抖音推荐算法!(教你如何上热门)
  16. OPPO AI Lab 核心岗位开放招聘:至美之路,等你加入!
  17. 谁来教我渗透测试——黑客必须掌握的Linux基础
  18. 《大学章句集注》-读书笔记之一
  19. MTK平台双卡区分SIM卡1和SIM卡2来电通知
  20. Linux快捷键汇总(持续更新)

热门文章

  1. Oracle 12C OUI安装
  2. PS 的打开文件和自由变换
  3. Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
  4. 磁珠Ferrite Bead 与电感inductance 的区别
  5. JavaScript:实现QuickSelectSearch快速选择搜索算法(附完整源码)
  6. 计算机组装实训台,计算机组装
  7. 你知道电源内部是怎么工作的吗
  8. 使用jsoup获取微信公众号文章发布时间
  9. APC新一代英飞集成系统 “智”关重要
  10. CAD中的各种Polyline