当前位置: 首页 > 工具软件 > mempool > 使用案例 >

DPDK无锁队列之MemPool理解

赵永逸
2023-12-01

应用

遍历mempool中的每一个元素

  • 查看mempool的相关接口的使用范例
# 参见 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】
 类似资料: