引言
DPDK的一大特点是使用大页(hugepage)进行内存管理,相比4KB页管理,使用大页可以减少页表大小,节省开销以及降低TLB miss的概率,从而提升应用访问内存的效率。在此基础上,DPDK主要实现了无锁队列ring,内存池mempool,内存堆heap来进行内存的分配和回收。
DPDK内存管理
开启大页
DPDK在非ARM平台上,最多支持三种尺寸(MAX_HUGEPAGE_SIZES
= 3)的大页,我们熟悉的x86系统上通常有2M和1G两种大页,我们可以在/etc/grub.conf
文件中配置默认大页,如:
//开启20G的大页,页大小为2MB(默认大小也为2M)
default_hugepagesz=2M hugepagesz=2M hugepages=10240
也可以按需修改,如:
echo 20480 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
开启大页后,将大页文件系统hugetlbfs挂载到目录下,用户程序就可以使用mmap映射大页文件来使用大页了
//将大页文件系统挂载到/mnt/huge目录下
mount –t hugetlbfs nodev /mnt/huge
内存初始化
DPDK的内存初始化,可以简单类比linux内存的初始化(buddy系统和slab系统),包括如下几个过程:
- 大页信息初始化
- dpdk buddy初始化(memzone,memseg list初始化&memseg 映射)
- dpdk slab初始化(heap初始化)
先上一张图, DPDK完成初始化后内存的顶层示意图,大页映射到挂载点下的文件,内部通过多个memseg list来管理大页:
大页信息初始化
dpdk根据系统的大页配置,初始化大页数组,计算每种大页数(统计每个numa节点上的可用页面数),核心的代码调用如下:
#枚举/sys/kernel/mm/hugepages目录下的大页,记录可用大页类型在internal_conf->hugep