[PATCH v12 5/6] memarea: support dump API

Chengwen Feng fengchengwen at huawei.com
Sat Jan 14 12:49:43 CET 2023


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

Signed-off-by: Chengwen Feng <fengchengwen at huawei.com>
Reviewed-by: Dongdong Liu <liudongdong3 at huawei.com>
---
 doc/guides/prog_guide/memarea_lib.rst |   3 +
 lib/memarea/rte_memarea.c             | 116 ++++++++++++++++++++++++++
 lib/memarea/rte_memarea.h             |  21 +++++
 lib/memarea/version.map               |   1 +
 4 files changed, 141 insertions(+)

diff --git a/doc/guides/prog_guide/memarea_lib.rst b/doc/guides/prog_guide/memarea_lib.rst
index 01187f7ccb..2b5326e717 100644
--- a/doc/guides/prog_guide/memarea_lib.rst
+++ b/doc/guides/prog_guide/memarea_lib.rst
@@ -37,6 +37,9 @@ the memarea.
 The ``rte_memarea_free()`` function is used to free one memory object which
 allocated by ``rte_memarea_alloc()``.
 
++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 76f8083d96..de473abe1d 100644
--- a/lib/memarea/rte_memarea.c
+++ b/lib/memarea/rte_memarea.c
@@ -302,3 +302,119 @@ rte_memarea_free(struct rte_memarea *ma, void *ptr)
 	}
 	memarea_unlock(ma);
 }
+
+static const char *
+memarea_source_name(enum rte_memarea_source source)
+{
+	if (source == RTE_MEMAREA_SOURCE_HEAP)
+		return "heap";
+	else if (source == RTE_MEMAREA_SOURCE_LIBC)
+		return "libc";
+	else if (source == RTE_MEMAREA_SOURCE_MEMAREA)
+		return "memarea";
+	else
+		return "unknown";
+}
+
+static const char *
+memarea_alg_name(enum rte_memarea_algorithm alg)
+{
+	if (alg == RTE_MEMAREA_ALGORITHM_NEXTFIT)
+		return "nextfit";
+	else
+		return "unknown";
+}
+
+static uint32_t
+memarea_obj_list_num(struct rte_memarea *ma)
+{
+	struct memarea_obj *obj;
+	uint32_t num = 0;
+
+	TAILQ_FOREACH(obj, &ma->obj_list, obj_node) {
+		if (obj->magic != MEMAREA_OBJECT_ALLOCATED_MAGIC &&
+		    obj->magic != MEMAREA_OBJECT_FREE_MAGIC)
+			break;
+		num++;
+	}
+
+	return num;
+}
+
+static uint32_t
+memarea_free_list_num(struct rte_memarea *ma)
+{
+	struct memarea_obj *obj;
+	uint32_t num = 0;
+
+	TAILQ_FOREACH(obj, &ma->free_list, free_node) {
+		if (obj->magic != MEMAREA_OBJECT_ALLOCATED_MAGIC &&
+		    obj->magic != MEMAREA_OBJECT_FREE_MAGIC)
+			break;
+		num++;
+	}
+
+	return num;
+}
+
+static size_t
+memarea_free_list_size(struct rte_memarea *ma)
+{
+	struct memarea_obj *obj;
+	size_t sz = 0;
+
+	TAILQ_FOREACH(obj, &ma->free_list, free_node) {
+		if (obj->magic != MEMAREA_OBJECT_ALLOCATED_MAGIC &&
+		    obj->magic != MEMAREA_OBJECT_FREE_MAGIC)
+			break;
+		sz += obj->size;
+	}
+
+	return sz;
+}
+
+static void
+memarea_dump_all_objects(struct rte_memarea *ma, FILE *f)
+{
+	struct memarea_obj *obj;
+
+	fprintf(f, "  objects:\n");
+	TAILQ_FOREACH(obj, &ma->obj_list, obj_node) {
+		if (obj->magic != MEMAREA_OBJECT_ALLOCATED_MAGIC &&
+		    obj->magic != MEMAREA_OBJECT_FREE_MAGIC) {
+			fprintf(f, "    magic: 0x%x check fail! stop dump!\n", obj->magic);
+			break;
+		}
+		fprintf(f, "    size: 0x%zx alloc-size: 0x%zx %s\n",
+			obj->size, obj->alloc_size,
+			obj->magic == MEMAREA_OBJECT_ALLOCATED_MAGIC ? "allocated" : "free");
+	}
+}
+
+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_HEAP)
+		fprintf(f, "  heap-numa-socket: %d\n", ma->init.numa_socket);
+	else if (ma->init.source == RTE_MEMAREA_SOURCE_MEMAREA)
+		fprintf(f, "  source-memarea: %s\n", ma->init.src_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-objects: %u\n", memarea_obj_list_num(ma));
+	fprintf(f, "  total-free-objects: %u\n", memarea_free_list_num(ma));
+	fprintf(f, "  total-free-objects-size: 0x%zx\n", memarea_free_list_size(ma));
+	fprintf(f, "  alloc-fails: %" PRIu64 "\n", ma->alloc_fails);
+	fprintf(f, "  magic_check_fails: %" PRIu64 "\n", ma->magic_check_fails);
+	if (dump_all)
+		memarea_dump_all_objects(ma, f);
+	memarea_unlock(ma);
+
+	return 0;
+}
diff --git a/lib/memarea/rte_memarea.h b/lib/memarea/rte_memarea.h
index 1e94685719..6d5093c47a 100644
--- a/lib/memarea/rte_memarea.h
+++ b/lib/memarea/rte_memarea.h
@@ -161,6 +161,27 @@ void *rte_memarea_alloc(struct rte_memarea *ma, size_t size, uint32_t align);
 __rte_experimental
 void rte_memarea_free(struct rte_memarea *ma, void *ptr);
 
+/**
+ * @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 effbd0b488..9513d91e0b 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;
 
 	local: *;
-- 
2.33.0



More information about the dev mailing list