DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init

本文介绍dpdk对rte_config->mem_config->memzones的初始化配置。

1 rte_fbarray_init

rte_eal_memzone_init主要就是调用了rte_fbarray_init。fbarry_init用来创建一块内存,存放一组element,每个element的大小相同。

1.1 rte_eal_memzone_init调用rte_fbarray_init,由传入参数可知:这组element的长度为RTE_MAX_MEMZONE=2560个,每个element的大小是sizeof(struct rte_memzone)=72bytes,申请并初始化成功之后挂到rte_config->mem_config->memzones下,且命名为“memzone”。
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第1张图片

1.2 计算所需要申请的空间

fbarray 分为data和mask两块空间,data空间为(element大小 * element长度),mask空间为一个mask list结构体+used mask域(mask空间需MASK_ALIGN对齐),每一个used mask的bit代码对应的element是否被使用。总空间(data+mask)需要以系统页面大小(4k)对齐。

实际例子中,memzone的element大小为72字节,长度为2560,所以data空间=72*2560=184,320‬ bytes
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第2张图片

mask空间为 mask list结构体大小(8字节) + element长度/8(bit转byte),所以mask size = 8 + 2560/8 = 328 bytes

所以总空间为 184,320‬+328 = 184,640‬,这个空间需以4k对齐,所以最后总空间为 (184,640‬/4096 向上取整 )*4096 = 46 *4096 = 188,416‬ bytes
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第3张图片

1.3 eal_get_virtual_area,获取fbarry空间所需的起始虚地址,且进行匿名mmap。

1.3.1 第一次进入函数时,全局变量next_baseaddr赋值成baseaddr。
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第4张图片
1.3.2 对齐处理
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第5张图片

1.3.3 匿名映射
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第6张图片
1.3.4 更新全局变量next_baseaddr,作为下次进入申请时的baseaddr。
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第7张图片

1.4 再次mmap?

resize and map.
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第8张图片

1.5 挂到arr(rte_config->mem_config->memzones)下
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第9张图片

2 总结

fbarray的数据结构图如下,所占的内存空间为文件映射区,以全局变量next_baseaddr控制映射区的累加。memzone_init的就是申请了memzone的fbarray空间。
DPDK学习记录9 - 内存初始化2之rte_eal_memzone_init_第10张图片

每个element存储了一个rte_memzone的结构体变量

/**
 * A structure describing a memzone, which is a contiguous portion of
 * physical memory identified by a name.
 */
struct rte_memzone {

#define RTE_MEMZONE_NAMESIZE 32       /**< Maximum length of memory zone name.*/
	char name[RTE_MEMZONE_NAMESIZE];  /**< Name of the memory zone. */

	RTE_STD_C11
	union {
		phys_addr_t phys_addr;        /**< deprecated - Start physical address. */
		rte_iova_t iova;              /**< Start IO address. */
	};
	RTE_STD_C11
	union {
		void *addr;                   /**< Start virtual address. */
		uint64_t addr_64;             /**< Makes sure addr is always 64-bits */
	};
	size_t len;                       /**< Length of the memzone. */

	uint64_t hugepage_sz;             /**< The page size of underlying memory */

	int32_t socket_id;                /**< NUMA socket ID. */

	uint32_t flags;                   /**< Characteristics of this memzone. */
} __attribute__((__packed__));

open issue: 为什么要两次mmap? get虚地址时已经匿名mmap过了,后面又mmap一次。

你可能感兴趣的:(DPDK)