dpdk内存管理--------初始化

 

https://www.cnblogs.com/MerlinJ/p/4074391.html

DPDK的内存初始化工作,主要是将hugetlbfs的配置的大内存页,根据其映射的物理地址是否连续、属于哪个Socket等,有效的组织起来,为后续管理提供便利。

eal_hugepage_info_init()

主要是获取配置好的Hugetlbfs的相关信息,并将其保存在struct internal_config数据结构中。

读取/sys/kernel/mm/hugepages目录下的各个子目录,通过判断目录名称中包含"hugepages-"字符串,获取hugetlbfs的相关子目录,并获取hugetlbfs配置的内存页大小。

通过读取/proc/mounts信息,找到hugetlbfs的挂载点

以打开文件的方式,打开挂载点目录,为其FD设置互斥锁

 hpi->hugepage_sz = 2M;
 hpi->hugedir = /mnt/huge;
 hpi->num_pages[0] = 64; // 由于此时还不知道哪些内存页分处在哪个socket上,故,都先放在socket-0上。
hpi->lock_descriptor = open(hpi->hugedir, O_RONLY); // 在读取hugetlbfs配置的时候,需要锁住整个目录。当所有hugepage都mmap完成后,会解锁。

rte_eal_config_create()

rte_eal_config_create()主要是初始化rte_config.mem_config。如果是以root用户运行dpdk程序的话,rte_config.mem_config指向/var/run/.rte_config文件mmap的一段sizeof(struct rte_mem_config)大小的内存。用于管理整个内存。

rte_eal_hugepage_init()

rte_eal_hugepage_init()主要是在/mnt/huge目录下创建hugetlbfs配置的内存页数的rtemap_xx文件,并为每个rtemap_xx文件做mmap映射,保证mmap后的虚拟地址与实际的物理地址 一致性。

有多少个内存页,在挂载点目录下创建多少个rtemap_xx文件,如下所示,并为每一个文件mmap一个hugepage_sz大小的内存区域。

通过读取/proc/self/pagemap页表文件,得到本进程中虚拟地址与物理地址的映射关系。使用上一步中,每个rtemap_xx文件mmap得到的虚拟地址,除以操作系统内存页的大小4k,得到一个偏移量。根据这个偏移量,在/prox/self/pagemap中,得到物理地址的页框,假设为page,那么,物理页框page乘以操作系统内存页的大小4K,再加上虚拟地址的页偏移,就是物理地址。每个rtemap_xx映射的物理地址保存在对应的hugepage_file->physaddr中。

读取/proc/self/numa_maps,得到每个rtemap_xx文件mmap得到的虚拟地址在哪个Socket上,即,哪个CPU上。其socketid保存在对应的hugepage_file->socket_id中

在hugepage_file数组中,根据物理地址,按从小到大的顺序,将hugepage_file排序。

根据按物理地址排序后的结果,判断物理地址是否连续,重新mmap /mnt/huge/retmap_xx文件,第二次mmap得到的虚拟地址保存在对应的hugepage_file->final_va中。

munmap释放第一步中各个rtemap_xx文件首次mmap得到的内存地址。

计算每个socket上包含多少个hugepage,信息保存在internal_config.hugepage_info[0].num_pages[socket]中。

rte_config.mem_config->memseg[]数组记录hugepage_file映射后物理地址连续的块数,hugepage_file->memseg_id为该huepage_file的物理地址在哪个rte_config.mem_config->memseg[]数组中。

rte_config.mem_config->memseg[j].phys_addr = 各物理地址是连续的内存块的首地址。

rte_config.mem_config->memseg[j].addr = 各个物理地址是连续的内存块对应的虚拟地址的首地址。由于物理地址和虚拟地址是相同的,这个值应该等于phys_addr。

rte_config.mem_config->memseg[j].len = 各个物理地址是连续的内存块的大小。

rte_config.mem_config->memseg[j].socket_id = 内存块在哪个socket上。。

rte_config.mem_config->memseg[j].hugepage_sz = hugepage内存页的大小。本文中是2M。

rte_eal_memzone_init()

rte_eal_memzone_init()主要负责初始化rte_config.mem_config->free_memseg[]及rte_config.mem_config->memzone[]。其中,rte_config.mem_config->free_memseg[]记录空闲的rte_config.mem_config->memseg[]。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值