bihash默认使用main-heap内存

2023-03-07 17:31:35 浏览数 (1)

前段时间在vpp交流群讨论bihash在默认条件下初始化的时候使用的是系统内存,还是大页内存。讨论也修正我的知识库,对bihash的理解也还停留在20.09版本之前。

基于20.09版本实现过一个项目针对tcp、sctp流实现重组、保序、去重等功能,并将处理过的流安全送给上层服务使用。创建五元组流表的无锁化设计是使用bihash来实现。为了提升性能,尝试将bihash使用内存调整为1G大页内存。测试效果来看性能提升很有限,只有2%左右性能提升。使用bihash_16_8.h类型在nat,ip报文重组、acl模块等都有使用,导致1G大页内存消耗过多。评估之后就保持使用系统内存了。

在bihash_template.h文件中设置大页内存的大小,默认2M;通过修改宏定义可以设置成1G大页内存。具体如下所示:

代码语言:javascript复制
/* default is 2MB, use 30 for 1GB */
#ifndef BIHASH_LOG2_HUGEPAGE_SIZE
#define BIHASH_LOG2_HUGEPAGE_SIZE 21
#endif

bihash 内存申请使用mmap映射的基地址,使用BV (alloc_aligned)函数中从基地址开始默认按照2M大页内存映射;如果系统没有设置大页或者大页内存不足,会再次按照系统页大小申请。

代码语言:javascript复制
static inline void *BV (alloc_aligned) (BVT (clib_bihash) * h, uword nbytes)
{
 ....
     #系统内存mmap flags参数
     int mmap_flags = MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS;
     #使用大页内存mmap flags参数设置。
     int mmap_flags_huge = (mmap_flags | MAP_HUGETLB | MAP_LOCKED |
                 BIHASH_LOG2_HUGEPAGE_SIZE << MAP_HUGE_SHIFT);
      /* round allocation to page size */
      alloc = round_pow2 (alloc, 1 << BIHASH_LOG2_HUGEPAGE_SIZE);

      base = (void *) (uword) (alloc_arena (h)   alloc_arena_mapped (h));
      #先尝试在大页内存上申请。
      rv = mmap (base, alloc, PROT_READ | PROT_WRITE, mmap_flags_huge, -1, 0);

      /* fallback - maybe we are still able to allocate normal pages 
      *大页内存申请失败后,跳转到从系统内存上分配*/
      if (rv == MAP_FAILED || mlock (base, alloc) != 0)
    rv = mmap (base, alloc, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);

      if (rv == MAP_FAILED)
    os_out_of_memory ();
...
}

其中mmap flags参数中MAP_HUGETLB表示使用大页创建映射(huge page),需要与MAP_HUGE_2MB 或MAP_HUGE_IGB结合使用,用于指定需要使用多大(2M或1GB)的大页内存。可以通过下面命令查询当前系统大页支持情况:

代码语言:javascript复制
#当前环境支持2M和1GB大页内存
ls /sys/kernel/mm/hugepages
hugepages-1048576kB  hugepages-2048kB
#查询大页数量,512个2M大页内存:也就是1G。1GB大页内存数量为0.
[root@jsh-vcpe-0001 ~]# cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
512
[root@jsh-vcpe-0001 ~]# cat /sys/kernel/mm/hugepages/hugepages-1048576kB/nr_hugepages
0
#也可以使用下面命令直接查询大内内存使用情况。
[root@jsh-vcpe-0001 ~]# cat /proc/meminfo  | grep Huge
AnonHugePages:    444416 kB
HugePages_Total:     512
HugePages_Free:      430
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

从21.01版本开始main heap 支持配置使用大页内存。可以通过startup.conf文件中进行指定。合入记录如下。

代码语言:javascript复制
commit 1965f750bf5f399a11c75d7ba14a52a504c69227
Author: Damjan Marion <damarion@cisco.com>
Date:   Fri Sep 11 22:18:35 2020  0200

    vpp: make main heap page size configurable from startup.conf

    Type: improvement
    Change-Id: I190c6896152c626aa7cb1055cfce5d9cfcd5b68b
    Signed-off-by: Damjan Marion <damarion@cisco.com>

对应startup.conf配置文件参数如下:

代码语言:javascript复制
# memory {
    ## Set the main heap size, default is 1G
    # 设置main heap大小,缺省是1G大小
    # main-heap-size 2G

    ## Set the main heap page size. Default page size is OS default page
    ## which is in most cases 4K. if different page size is specified VPP
    ## will try to allocate main heap by using specified page size.
    ## special keyword 'default-hugepage' will use system default hugepage
    ## size
    #设置main heap 页大小。缺省页大小是系统默认页大小,大多数情况是4K。
   #如果指定了页大小,vpp会尝试使用指定的页大小分配main heap。
    # main-heap-page-size 1G
    ## Set the default huge page size.
    # default-hugepage-size 1G
#

main heap中可以通过startup.conf文件来设置使用大页内存。bihash也进行了相应的适配修改。BIHASH_USE_HEAP来控制bihash内存是否使用main heap内存。相应的patch记录如下:

代码语言:javascript复制
commit 2454de2d4539943d4140839facf6a2a2ea795556
Author: Damjan Marion <damarion@cisco.com>
Date:   Sat Sep 26 19:32:34 2020  0200

    vppinfra: use heap to store bihash data

    Type: improvement
    Change-Id: Ifb0fa114414aa2fdc244f964612ca3ac3e29b5e1
    Signed-off-by: Damjan Marion <damarion@cisco.com>

这样vpp除vlib_buffer_t 报文缓存区特殊申请之外,其他内存申请大部分都是在main heap申请了吧。可以使用命令行show memory main-heap 来观察内存使用及是否使用大爷内存等等:

代码语言:javascript复制
vpp# show memory main-heap verbose
Thread 0 vpp_main
  base 0x7f25963c6000, size 1g, locked, unmap-on-destroy, name 'main heap'
    page stats: page-size 4K, total 262144, mapped 2735, not-mapped 244544, unknown 14865
      numa 0: 2735 pages, 10.68m bytes
    total: 1023.99M, used: 65.08M, free: 958.92M, trimmable: 958.26M
      free chunks 44 free fastbin blks 0
      max total allocated 1023.99M

Thread 1 vpp_wk_0
  base 0x7f25963c6000, size 1g, locked, unmap-on-destroy, name 'main heap'
    page stats: page-size 4K, total 262144, mapped 2735, not-mapped 244544, unknown 14865
      numa 0: 2735 pages, 10.68m bytes
    total: 1023.99M, used: 65.08M, free: 958.92M, trimmable: 958.26M
      free chunks 43 free fastbin blks 0
      max total allocated 1023.99M
vpp#

由此可以总结如下:

21.01之前版本(不含21.01),bihash内存默认使用2M大页内存来申请,可以通过设置宏定义BIHASH_LOG2_HUGEPAGE_SIZE =30 来使用1G大页,当大页内存映射失败之后,使用系统内存页来申请内存。

21.01及之后的版本,bihash内存默认使用main heap内存。可以通过设置BIHASH_USE_HEAP宏定义=0来取消。

0 人点赞