DPDK学习记录10 - 内存初始化3之rte_eal_memseg_init

对rte_config->mem_config->memsegs 数组进行配置。primary进程调用memseg_primary_init。

struct rte_mem_config {
	struct rte_memseg_list memsegs[RTE_MAX_MEMSEG_LISTS]; 	/**< list of dynamic arrays holding memsegs */
} __attribute__((__packed__));

#define RTE_MAX_MEMSEG_LISTS 128
/**
 * memseg list is a special case as we need to store a bunch of other data
 * together with the array itself.
 */
struct rte_memseg_list {
	RTE_STD_C11
	union {
		void *base_va;		/**< Base virtual address for this memseg list. */
		uint64_t addr_64;		/**< Makes sure addr is always 64-bits */
	};
	uint64_t page_sz; /**< Page size for all memsegs in this list. */ //每个大页的字节数2048*1024
	int socket_id; /**< Socket ID for all memsegs in this list. */
	volatile uint32_t version; /**< version number for multiprocess sync. */
	size_t len; /**< Length of memory area covered by this memseg list. */ //这里是以字节为单位,本文例子中为 8192*2048*1024(memseg个数*2MB)
	unsigned int external; /**< 1 if this list points to external memory */
	struct rte_fbarray memseg_arr; //(这里存储着memseg个数,也就是页面的数目,本例中为8192)
};

1. gdb

1.1 n_memtype由internal_config.num_hugepage_sizes * rte_socket_count()得到,这里是1。

在这里插入图片描述

1.2 计算每个memtype中, seg_list个数和每个list里面的segs个数。

在这里插入图片描述

1.3 在每一个memtype中,根据上面的n_seglists = 4,分别创建每一个memseg list。分为两步,第一步alloc_memseg_list,第二步alloc_va_space。

1.3.1 第一步alloc_memseg_list
主要内容是通过rte_fbarray_init函数对rte_memseg_list中的memseg_arr进行赋值,fbarray中的每个element对应一个大页,element个数(即大页个数len)为8192个,每个element的大小(elt_sz)为48字节,每个element结构为

struct rte_memseg {
	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 segment. */
	uint64_t hugepage_sz;       /**< The pagesize of underlying memory */
	int32_t socket_id;          /**< NUMA socket ID. */
	uint32_t nchannel;          /**< Number of channels. */
	uint32_t nrank;             /**< Number of ranks. */
	uint32_t flags;             /**< Memseg-specific flags */
} __rte_packed;

最后获得的memseg_arr中,data地址为0x10002e000,是紧接着memzones地址之后。
在这里插入图片描述
1.3.2 第二步alloc_va_space
memseg_arr仅仅是保存rte_memseg结构的管理内存,真正的大页内存是申请到rte_memseg_list的base_va下面,这个地址需要以2MB对齐,所以最终的地址是0x100200000,这个地址开始需要占用的内存即为len中的字节数:81922MB = 8192210241024 = 17,179,869,184‬ = 0x400000000‬。所以此时next_baseaddr全局变量应该为 0x100200000+0x400000000‬ = 0x500200000。

从0x10002e000到0x100200000,memseg_arr用不了那么多内存,后面很大一段是为了对齐浪费的。
在这里插入图片描述

1.4 所有4个memseg list分别创建之后,rte_config->mem_config->memsegs下的最终结果如下:
在这里插入图片描述

2. 总结

rte_eal_memseg_init对rte_config->mem_config->memsegs进行了初始化配置,是按照不同的socket和不同的page size,管理了多个memtype,每个memtype中再初始化多个memseg list,每个memseg list再初始化多个memsegs。其中,memtype个数是准确的(socket个数 乘以 page_size个数),而memseg list个数和memsegs个数,是按照最大数目来初始化的。我这里大页只配置了512个memsegs,实际上却初始化了4 乘以 8192个memsegs。
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值