dpdk内存管理

dpdk的两大特色igb_uio和共享内存,而igb_uio也是建立在共享内存的基础上的。本文就dpdk内存相关的知识做一下梳理,加深一下对这方面知识的理解,并提供一些解决问题的手段。
1、dpdk共享内存采用的hugepage技术
hugepage的配置之前的文章已经讲解过了,这儿需要了解 一下hugepage的基本原理。
可以参考: http://blog.csdn.net/jy1075518049/article/details/43610569
因为dpdk涉及到虚拟地址到物理地址的转换:    physaddr= ((page & 0x7fffffffffffffULL) * page_size) + ((unsigned long)virtaddr % page_size);
dpdk涉及到的共享内存有:
a、 hugapage用于数据转发,进程之间共享数据结构等用途
b、物理网卡配置部分的贡献内存,寄存器地址
2、hugepage
dpdk内存管理_第1张图片
a) 内存访问时间取决于处理器的内存位置,cpu访问本地内存的速度要快。
b) 文件 -page - memory的映射关系,文件映射的虚拟内存在mapping segment

dpdk内存管理_第2张图片
3、dpdk hugepage初始化
1)需根据系统配置的hugepage,获取page类型以及对应的page数量,并生成对应page文件,并通过相应的数据结构记录hugepage相关的信息
eal_hugepage_info_init();
hugepage 信息记录到internal_config的
struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
2)有了hugepage信息以后,后续就是内存映射,初始化内存,保证用户维护和使用简单。也就是dpdk的内存管理。
rte_eal_memory_init()
master core初始化内存
slave core通过获取内存配置信息在初始化自己的内存
a、创建每个page文件的数据结构
主要用于记录,每个文件映射后的虚拟内存地址,物理内存地址等信息
struct hugepage_file {
void *orig_va; /**< virtual addr of first mmap() */
void *final_va; /**< virtual addr of 2nd mmap() */
uint64_t physaddr; /**< physical addr */
size_t size; /**< the page size */
int socket_id; /**< NUMA socket ID */
int file_id; /**< the '%d' in HUGEFILE_FMT */
int memseg_id; /**< the memory segment to which page belongs */
#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
int repeated; /**< number of times the page size is repeated */
#endif
char filepath[MAX_HUGEPAGE_PATH]; /**< path to backing file on filesystem */
};
b、进行hugepage地址映射
10个page 每个page2M
aa)第一次映射。映射10*2M的虚拟内存空间vir_addr,保证每个page的虚拟地址是连续的,虚拟地址首地址可以指定
http://blog.csdn.net/q_l_s/article/details/51889004
static void* hugepage_addr = (void*)(0x7b0000000000);
static void* hugepage_info_addr = (void*)(0x7a0000000000);
static void* rte_config_addr = (void*)(0x7a1000000000);
虚拟地址为什么要连续?
bb)把每个hugepage依次映射到,vir_addr范围内
rtemap_0 : vir_addr
rtemap_1 : vir_addr + page_size
……
rtemap_n : vir_addr + n*page_size
c、物理地址到虚拟地址转换
把每一个page的虚拟地址映射到对应的物理地址。
physaddr = ((page & 0x7fffffffffffffULL) * page_size)+ ((unsigned long)virtaddr % page_size);
从/proc/self/pagemap获取page
思考一下如何进行的TLB转换,特别是细节,对于Linux内存管理会进一步加深理解?
d、把每个hugepage按物理地址大小进行排序,
e、重新映射hugepage
保证虚拟地址尽可能连续
保证物理地址尽可能连续
dpdk内存管理_第3张图片
上图描述了
第一次映射,虚拟地址连续,物理地址肯能不连续
物理地址排序,排序后page顺序发生变化,虚拟地址不再连续
第二次映射,物理地址连续,虚拟地址也连续
f、unmap第一次映射的虚拟地址
g、映射共享内存。保存记录内存信息的数据结构,此后对内存的访问都要基于这个数据结构。如果这部分内存被破坏,对大页内存的访问将会出现异常。
h、物理内存信息记录到memseg中。

dpdk内存管理_第4张图片
4、heap的构造以及如何使用
构造heap的基本原因,把属于对应socket的memseg插入对应的list。


dpdk内存管理_第5张图片

待续。。。。。。

你可能感兴趣的:(DPDK)