文章目录
- 前言
- Mempool工作机制
- Mempool数据结构
- rte_mempool_ops
- Mempool操作接口
- rte_mempool_create:创建Mempool
- rte_mempool_get:申请对象
- rte_mempool_put:释放对象
- 相关参考
前言
DPDK提供了一套内存池管理机制,以提供高效分配固定大小对象的能力。
Mempool工作机制
Mempool内部维护两级空闲对象缓存:Per-Core缓存和共享缓存,其中:
- Per-Core缓存为每个在用的CPU core分配了专用的空闲对象池,避免了当前运行CPU core分配内存时与其它CPU core的冲突;
- 共享缓存提供了在Per-Core缓存不足时,仍能分配空闲对象的能力。
Mempool工作机制示意如下:
应用申请对象时,Mempool优先从Per-core缓存进行分配,在Per-core缓存不足时,从共享池中进行分配。Per-core缓存和共享池都是基于DPDK Ring数据结构进行组织,并使用Ring接口完成空闲对象的分配与回收。
Mempool数据结构
Mempool核心数据结构关联如下:
- rte_mempool:Mempool管理结构;
- rte_mempool_cache:Per-core缓存,维护了一个共享对象的数组队列;
- rte_mempool_memhdr:管理共享缓存的后端内存;
- rte_mempool_objhdr:Object管理结构,位于对象头部。
rte_mempool_ops
DPDK Mempool在创建时,会为Mempool初始化一套回调接口,通过这套接口,上层应用可以自定义共享缓存的构建方式,并根据业务场景定制共享缓存对象的的分配和释放实现。rte_mempool_ops结构定义如下:
struct rte_mempool_ops {
char name[RTE_MEMPOOL_OPS_NAMESIZE];
rte_mempool_alloc_t alloc;
rte_mempool_free_t free;
rte_mempool_enqueue_t enqueue;
rte_mempool_dequeue_t dequeue;
rte_mempool_get_count get_count;
rte_mempool_calc_mem_size_t calc_mem_size;
rte_mempool_populate_t populate;
rte_mempool_get_info_t get_info;
rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks;
} __rte_cache_aligned;
DPDK框架使用rte_mempool_ops_table变量维护所有类型的Mempool回调接口,应用可以通过RTE_MEMPOOL_REGISTER_OPS宏进行注册。
struct rte_mempool_ops_table rte_mempool_ops_table = {
.sl = RTE_SPINLOCK_INITIALIZER,
.num_ops = 0
};
#define RTE_MEMPOOL_REGISTER_OPS(ops) \
RTE_INIT(mp_hdlr_init_##ops) \
{ \
rte_mempool_register_ops(&ops); \
}
DPDK框架默认内置了几种类型的操作回调,这些回调主要利用DPDK Ring来对共享缓存对象进行组织,同时使用Ring提供的操作接口来分配和释放对象。
RTE_MEMPOOL_REGISTER_OPS(ops_mp_mc);
RTE_MEMPOOL_REGISTER_OPS(ops_sp_sc);
RTE_MEMPOOL_REGISTER_OPS(ops_mp_sc);
RTE_MEMPOOL_REGISTER_OPS(ops_sp_mc);
Mempool操作接口
rte_mempool_create:创建Mempool
rte_mempool_get:申请对象
rte_mempool_get负责完成从一个Mempool中需求对象的的分配。
- Per-core缓存维护了一个空闲对象的数组队列。当Per-core缓存能满足分配需求时,则直接操作Per-core缓存区域获取;
- 若Per-core缓存无法满足要求,则先从共享缓存中获取超量的对象填充Per-core缓存,最后再从Per-core缓存中分配。
rte_mempool_put:释放对象
rte_mempool_put负责将不使用的对象释放回Mempool中。
- Per-core缓存维护的空闲对象数组,空间比Per-core支持分配的大小要大的多,可以用来临时存放上层应用释放的对象;
- 当Per-core缓存已存放的对象数量超过配置的阀值时,需要刷到共享缓存中。
相关参考
- Mempool Library