[v5,05/10] memarea: support dump API

Message ID tencent_6E4DB9F7AB18D07BBF83ACE9ADFBE6F4F906@qq.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v5,01/10] memarea: introduce memarea library |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

datshan Oct. 5, 2022, 4:09 a.m. UTC
  From: Chengwen Feng <fengchengwen@huawei.com>

This patch supports rte_memarea_dump() API which could be used for
debug.

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 doc/guides/prog_guide/memarea_lib.rst |  3 +
 lib/memarea/rte_memarea.c             | 85 +++++++++++++++++++++++++++
 lib/memarea/rte_memarea.h             | 21 +++++++
 lib/memarea/version.map               |  1 +
 4 files changed, 110 insertions(+)
  

Patch

diff --git a/doc/guides/prog_guide/memarea_lib.rst b/doc/guides/prog_guide/memarea_lib.rst
index 41bc0a90cd..c77012fe44 100644
--- a/doc/guides/prog_guide/memarea_lib.rst
+++ b/doc/guides/prog_guide/memarea_lib.rst
@@ -43,6 +43,9 @@  The ``rte_memarea_update_refcnt()`` function is used to update the memory
 object's reference count, if the count reaches zero, the memory object will
 be freed to memarea.
 
++The ``rte_memarea_dump()`` function is used to dump the internal information
++of a memarea.
+
 Reference
 ---------
 
diff --git a/lib/memarea/rte_memarea.c b/lib/memarea/rte_memarea.c
index a072f07f20..b70830d0bb 100644
--- a/lib/memarea/rte_memarea.c
+++ b/lib/memarea/rte_memarea.c
@@ -2,6 +2,7 @@ 
  * Copyright(c) 2022 HiSilicon Limited
  */
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/queue.h>
@@ -298,3 +299,87 @@  rte_memarea_update_refcnt(struct rte_memarea *ma, void *ptr, int16_t value)
 		memarea_free_elem(ma, elem);
 	memarea_unlock(ma);
 }
+
+static const char *
+memarea_source_name(enum rte_memarea_source source)
+{
+	if (source == RTE_MEMAREA_SOURCE_RTE_MEMORY)
+		return "rte-memory";
+	else if (source == RTE_MEMAREA_SOURCE_SYSTEM_API)
+		return "system-api";
+	else if (source == RTE_MEMAREA_SOURCE_USER_ADDR)
+		return "user-addr";
+	else if (source == RTE_MEMAREA_SOURCE_USER_MEMAREA)
+		return "user-memarea";
+	else
+		return "unknown";
+}
+
+static const char *
+memarea_alg_name(enum rte_memarea_alg alg)
+{
+	if (alg == RTE_MEMAREA_ALG_DEFAULT)
+		return "default";
+	else
+		return "unknown";
+}
+
+static uint32_t
+memarea_elem_list_num(struct rte_memarea *ma)
+{
+	struct memarea_elem *elem;
+	uint32_t num = 0;
+
+	TAILQ_FOREACH(elem, &ma->elem_list, elem_node)
+		num++;
+
+	return num;
+}
+
+static uint32_t
+memarea_free_list_num(struct rte_memarea *ma)
+{
+	struct memarea_elem *elem;
+	uint32_t num = 0;
+
+	TAILQ_FOREACH(elem, &ma->free_list, free_node)
+		num++;
+
+	return num;
+}
+
+static void
+memarea_dump_all(struct rte_memarea *ma, FILE *f)
+{
+	struct memarea_elem *elem;
+
+	fprintf(f, "  regions:\n");
+	TAILQ_FOREACH(elem, &ma->elem_list, elem_node)
+		fprintf(f, "    size: 0x%zx cookie: 0x%x refcnt: %d\n",
+			elem->size, elem->cookie, elem->refcnt);
+}
+
+int
+rte_memarea_dump(struct rte_memarea *ma, FILE *f, bool dump_all)
+{
+	if (ma == NULL || f == NULL)
+		return -EINVAL;
+
+	memarea_lock(ma);
+	fprintf(f, "memarea name: %s\n", ma->init.name);
+	fprintf(f, "  source: %s\n", memarea_source_name(ma->init.source));
+	if (ma->init.source == RTE_MEMAREA_SOURCE_USER_MEMAREA)
+		fprintf(f, "  source-user-memarea: %s\n", ma->init.user_memarea->init.name);
+	fprintf(f, "  algorithm: %s\n", memarea_alg_name(ma->init.alg));
+	fprintf(f, "  total-size: 0x%zx\n", ma->init.total_sz);
+	fprintf(f, "  mt-safe: %s\n", ma->init.mt_safe ? "yes" : "no");
+	fprintf(f, "  total-regions: %u\n", memarea_elem_list_num(ma));
+	fprintf(f, "  total-free-regions: %u\n", memarea_free_list_num(ma));
+	fprintf(f, "  alloc_fails: %" PRIu64 "\n", ma->alloc_fails);
+	fprintf(f, "  refcnt_check_fails: %" PRIu64 "\n", ma->refcnt_check_fails);
+	if (dump_all)
+		memarea_dump_all(ma, f);
+	memarea_unlock(ma);
+
+	return 0;
+}
diff --git a/lib/memarea/rte_memarea.h b/lib/memarea/rte_memarea.h
index 10e0d6ad5a..10b8229c64 100644
--- a/lib/memarea/rte_memarea.h
+++ b/lib/memarea/rte_memarea.h
@@ -194,6 +194,27 @@  void rte_memarea_free(struct rte_memarea *ma, void *ptr);
 __rte_experimental
 void rte_memarea_update_refcnt(struct rte_memarea *ma, void *ptr, int16_t value);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Dump memarea.
+ *
+ * Dump one memarea.
+ *
+ * @param ma
+ *   The pointer of memarea.
+ * @param f
+ *   The file to write the output to.
+ * @param dump_all
+ *   Indicate whether to dump the allocated and free memory objects information.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_experimental
+int rte_memarea_dump(struct rte_memarea *ma, FILE *f, bool dump_all);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/memarea/version.map b/lib/memarea/version.map
index a0026fc5f9..d8ddd93c13 100644
--- a/lib/memarea/version.map
+++ b/lib/memarea/version.map
@@ -4,6 +4,7 @@  EXPERIMENTAL {
 	rte_memarea_alloc;
 	rte_memarea_create;
 	rte_memarea_destroy;
+	rte_memarea_dump;
 	rte_memarea_free;
 	rte_memarea_update_refcnt;