# 参见 DPDK 源码的 dpdk/test/test/test_mempool.c 文件。
static int
test_mempool(void)
{
int ret = -1;
struct rte_mempool *mp_cache = NULL;
struct rte_mempool *mp_nocache = NULL;
struct rte_mempool *mp_stack = NULL;
struct rte_mempool *default_pool = NULL;
const char *default_pool_ops = rte_mbuf_best_mempool_ops();
rte_atomic32_init(&synchro);
/* create a mempool (without cache) */
mp_nocache = rte_mempool_create("test_nocache", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE, 0, 0,
NULL, NULL,
my_obj_init, NULL,
SOCKET_ID_ANY, 0);
if (mp_nocache == NULL) {
printf("cannot allocate mp_nocache mempool\n");
goto err;
}
/* create a mempool (with cache) */
mp_cache = rte_mempool_create("test_cache", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE,
RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
NULL, NULL,
my_obj_init, NULL,
SOCKET_ID_ANY, 0);
if (mp_cache == NULL) {
printf("cannot allocate mp_cache mempool\n");
goto err;
}
/* create a mempool with an external handler */
mp_stack = rte_mempool_create_empty("test_stack",
MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE,
RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
SOCKET_ID_ANY, 0);
if (mp_stack == NULL) {
printf("cannot allocate mp_stack mempool\n");
goto err;
}
if (rte_mempool_set_ops_byname(mp_stack, "stack", NULL) < 0) {
printf("cannot set stack handler\n");
goto err;
}
if (rte_mempool_populate_default(mp_stack) < 0) {
printf("cannot populate mp_stack mempool\n");
goto err;
}
rte_mempool_obj_iter(mp_stack, my_obj_init, NULL);
/* Create a mempool based on Default handler */
printf("Testing %s mempool handler\n", default_pool_ops);
default_pool = rte_mempool_create_empty("default_pool",
MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE,
RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
SOCKET_ID_ANY, 0);
if (default_pool == NULL) {
printf("cannot allocate default mempool\n");
goto err;
}
if (rte_mempool_set_ops_byname(default_pool,
default_pool_ops, NULL) < 0) {
printf("cannot set %s handler\n", default_pool_ops);
goto err;
}
if (rte_mempool_populate_default(default_pool) < 0) {
printf("cannot populate %s mempool\n", default_pool_ops);
goto err;
}
rte_mempool_obj_iter(default_pool, my_obj_init, NULL);
/* retrieve the mempool from its name */
if (rte_mempool_lookup("test_nocache") != mp_nocache) {
printf("Cannot lookup mempool from its name\n");
goto err;
}
printf("Walk into mempools:\n");
rte_mempool_walk(walk_cb, NULL);
rte_mempool_list_dump(stdout);
/* basic tests without cache */
if (test_mempool_basic(mp_nocache, 0) < 0)
goto err;
/* basic tests with cache */
if (test_mempool_basic(mp_cache, 0) < 0)
goto err;
/* basic tests with user-owned cache */
if (test_mempool_basic(mp_nocache, 1) < 0)
goto err;
/* more basic tests without cache */
if (test_mempool_basic_ex(mp_nocache) < 0)
goto err;
/* mempool operation test based on single producer and single comsumer */
if (test_mempool_sp_sc() < 0)
goto err;
if (test_mempool_creation_with_exceeded_cache_size() < 0)
goto err;
if (test_mempool_same_name_twice_creation() < 0)
goto err;
/* test the stack handler */
if (test_mempool_basic(mp_stack, 1) < 0)
goto err;
if (test_mempool_basic(default_pool, 1) < 0)
goto err;
rte_mempool_list_dump(stdout);
ret = 0;
err:
rte_mempool_free(mp_nocache);
rte_mempool_free(mp_cache);
rte_mempool_free(mp_stack);
rte_mempool_free(default_pool);
return ret;
}
注:重点关注 rte_mempool_lookup、rte_mempool_obj_iter、rte_mempool_list_dump、rte_mempool_walk 、rte_mempool_dump、
基于 rte_mempool_obj_iter 的实现:
使用gdb 遍历mempool中的每一个元素,以下为 mbuf的mempool中的元素的遍历的例子:
1》 mbuf mempool 的信息:
(gdb) p *(struct rte_mempool *) 0x1764ec900
$2 = {
name = "mbuf_pool_0", '\000' <repeats 20 times>,
{
pool_data = 0x175cec740,
pool_id = 6271452992
},
pool_config = 0x0,
mz = 0x100000318,
flags = 16,
socket_id = 0,
size = 1048575,
cache_size = 256,
elt_size = 2312,
header_size = 64,
trailer_size = 120,
private_data_size = 64,
ops_index = 0,
local_cache = 0x1764ec9c0,
populated_size = 1048575,
elt_list = {
stqh_first = 0x1c0000028,
stqh_last = 0x25bffed28
},
nb_mem_chunks = 2,
mem_list = {
stqh_first = 0x17f986980,
stqh_last = 0x17f986900
}
}
2》打印第一个mbuf
mempool第一个obj的hdr信息:
(gdb) p *(struct rte_mempool_objhdr *) 0x1c0000028
$18 = {
next = {
stqe_next = 0x1c00009e8
},
mp = 0x1764ec900,
{
iova = 32212254784,
physaddr = 32212254784
}
}
第一个mbuf的信息:
(gdb) p * (struct rte_mbuf *) (0x1c0000028 + sizeof(struct rte_mempool_objhdr))
3》打印所有的mbuf 信息到文件中。
(gdb) set logging off
Done logging to /home/dpvs_gdb.out.
(gdb) set logging file /home/dpvs_gdb_port0_mbuf_info
(gdb) set logging on
Copying output to /home/dpvs_gdb_port0_mbuf_info.
Copying debug output to /home/dpvs_gdb_port0_mbuf_info.
(gdb) set $mempool_objhdr_aaa = (struct rte_mempool_objhdr *) 0x1c0000028
(gdb) while $mempool_objhdr_aaa
>set $mbuf_aaa = (struct rte_mbuf *) (((char *)$mempool_objhdr_aaa) + sizeof(struct rte_mempool_objhdr))
>if (((struct rte_mbuf *)$mbuf_aaa)->nb_segs != 0 && ((struct rte_mbuf *)$mbuf_aaa)->port == 0)
>p *(struct rte_mbuf *) $mbuf_aaa
>end
>set $mempool_objhdr_aaa = (struct rte_mempool_objhdr *) (((struct rte_mempool_objhdr *)$mempool_objhdr_aaa)->next.stqe_next)
>end
https://doc.dpdk.org/guides/prog_guide/index.html
【DPDK programmer guide】