前段时间在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来取消。