DPDK patches and discussions
 help / color / mirror / Atom feed
* [RFC] memarea: introduce memory area library
@ 2022-07-21  4:46 Chengwen Feng
  2022-07-21 15:22 ` Stephen Hemminger
                   ` (23 more replies)
  0 siblings, 24 replies; 222+ messages in thread
From: Chengwen Feng @ 2022-07-21  4:46 UTC (permalink / raw)
  To: thomas; +Cc: dev

The memarea library is an allocator of variable-size object. It is a
collection of allocated objects that can be efficiently alloc or free
all at once, the main feature are as follows:
a) it facilitate alloc and free of memory with low overhead.

b) it provides refcnt feature which could be useful in some scenes.

c) it supports MT-safe as long as it's specified at creation time.

d) it's memory source could comes from:
d.1) system API: malloc in C library.
d.2) user provided address: it can be from the rte_malloc API series
or extended memory as long as it is available.
d.3) user provided memarea: it can be from another memarea.

Note:
a) the memarea is oriented towards the application layer, which could
provides 'region-based memory management' [1] function.
b) the eal library also provide memory zone/heap management, but these
are tied to huge pages management.

[1] https://en.wikipedia.org/wiki/Region-based_memory_management

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 lib/memarea/meson.build   |  10 ++
 lib/memarea/rte_memarea.c |  52 ++++++++++
 lib/memarea/rte_memarea.h | 205 ++++++++++++++++++++++++++++++++++++++
 lib/memarea/version.map   |  16 +++
 lib/meson.build           |   1 +
 5 files changed, 284 insertions(+)
 create mode 100644 lib/memarea/meson.build
 create mode 100644 lib/memarea/rte_memarea.c
 create mode 100644 lib/memarea/rte_memarea.h
 create mode 100644 lib/memarea/version.map

diff --git a/lib/memarea/meson.build b/lib/memarea/meson.build
new file mode 100644
index 0000000000..d5c2c442f5
--- /dev/null
+++ b/lib/memarea/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2022 HiSilicon Limited
+
+sources = files(
+        'rte_memarea.c',
+)
+headers = files(
+        'rte_memarea.h',
+)
+deps += []
diff --git a/lib/memarea/rte_memarea.c b/lib/memarea/rte_memarea.c
new file mode 100644
index 0000000000..2989b56c60
--- /dev/null
+++ b/lib/memarea/rte_memarea.c
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 202 HiSilicon Limited
+ */
+
+#include <rte_common.h>
+#include <rte_memarea.h>
+
+struct rte_memarea *
+rte_memarea_create(const struct rte_memarea_param *init)
+{
+	RTE_SET_USED(init);
+	return NULL;
+}
+
+int
+rte_memarea_destroy(struct rte_memarea *ma)
+{
+	RTE_SET_USED(ma);
+	return 0;
+}
+
+void *
+rte_memarea_alloc(struct rte_memarea *ma, uint32_t size)
+{
+	RTE_SET_USED(ma);
+	RTE_SET_USED(size);
+	return NULL;
+}
+
+void
+rte_memarea_free(struct rte_memarea *ma, void *ptr)
+{
+	RTE_SET_USED(ma);
+	RTE_SET_USED(ptr);
+}
+
+int
+rte_memarea_refcnt_update(struct rte_memarea *ma, void *ptr, int16_t value)
+{
+	RTE_SET_USED(ma);
+	RTE_SET_USED(ptr);
+	RTE_SET_USED(value);
+	return 0;
+}
+
+int
+rte_memarea_dump(struct rte_memarea *ma, FILE *f)
+{
+	RTE_SET_USED(ma);
+	RTE_SET_USED(f);
+	return 0;
+}
diff --git a/lib/memarea/rte_memarea.h b/lib/memarea/rte_memarea.h
new file mode 100644
index 0000000000..dfbe845595
--- /dev/null
+++ b/lib/memarea/rte_memarea.h
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 HiSilicon Limited
+ */
+
+#ifndef RTE_MEMAREA_H
+#define RTE_MEMAREA_H
+
+/**
+ * @file
+ * RTE Memarea.
+ *
+ * A memory area is an allocator of variable-size object. It is identified
+ * by its name.
+ *
+ * The memarea is a collection of allocated objects that can be efficiently
+ * alloc or free all at once, the main feature are as follows:
+ *   a) it facilitate alloc and free of memory with low overhead.
+ *   b) it provides refcnt feature which could be useful in some scenes.
+ *   c) it supports MT-safe as long as it's specified at creation time.
+ *   d) it's memory source could comes from:
+ *      d.1) system API: malloc in C library.
+ *      d.2) user provided address: it can be from the rte_malloc API series
+ *           or extended memory as long as it is available.
+ *      d.3) user provided memarea: it can be from another memarea. So we can
+ *           build the following memory management structure:
+ *                         memarea-1
+ *                             |
+ *                             v
+ *                 ------------------------
+ *                 |           |          |
+ *                 v           v          v
+ *              memarea-2   memarea-3    obj
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include <rte_compat.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RTE_MEMAREA_NAMESIZE	64
+
+/**
+ * Memarea memory source.
+ */
+enum rte_memarea_source {
+	/** Memory source comes from sys api (e.g. malloc) */
+	RTE_MEMAREA_SOURCE_SYSAPI,
+	/** Memory source comes from user-provided address */
+	RTE_MEMAREA_SOURCE_USER_ADDR,
+	/** Memory source comes from user-provided memarea */
+	RTE_MEMAREA_SOURCE_USER_MEMAREA,
+};
+
+struct rte_memarea;
+
+struct rte_memarea_param {
+	char name[RTE_MEMAREA_NAMESIZE]; /**< Name of memarea */
+	enum rte_memarea_source source;  /**< Memory source of memarea */
+	uint64_t size;                   /**< Size (byte) of memarea */
+	uint32_t align;                  /**< Align of allocated object */
+	/** Indicates whether the memarea should be MT-safe */
+	bool mt_safe;
+	/** Indicates whether the memarea is visible to multiple process.
+	 * If the memory source is RTE_MEMAREA_SOURCE_USER_ADDR, this filed
+	 * depends on user settings and must be set.
+	 * If the memory source is RTE_MEMAREA_SOURCE_SYSAPI or
+	 * RTE_MEMAREA_SOURCE_USER_MEMAREA, this filed does not need to be set.
+	 */
+	bool mp_visible;
+	/** User provided address, this field is valid only when source
+	 * is set to RTE_MEMAREA_SOURCE_USER_ADDR.
+	 */
+	void *user_addr;
+	/** User provided memarea, this field is valid only when source
+	 * is set to RTE_MEMAREA_SOURCE_MEMAREA.
+	 */
+	struct rte_memarea *user_memarea;
+};
+
+struct rte_memarea {
+	void *private_data; /**< private management data pointer*/
+	struct rte_memarea_param init;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Create memarea.
+ *
+ * Create one new memarea.
+ *
+ * @param init
+ *   The init parameter of memarea.
+ *
+ * @return
+ *   Non-NULL on success. Otherwise NULL is returned.
+ */
+__rte_experimental
+struct rte_memarea *rte_memarea_create(const struct rte_memarea_param *init);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Destroy memarea.
+ *
+ * Destroy the memarea.
+ *
+ * @param ma
+ *   The pointer of memarea.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_experimental
+int rte_memarea_destroy(struct rte_memarea *ma);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Allocate memory from memarea.
+ *
+ * Allocate one memory region from the memarea.
+ *
+ * @param ma
+ *   The pointer of memarea.
+ * @param size
+ *   The memory size to be allocated.
+ *
+ * @return
+ *   Non-NULL on success. Otherwise NULL is returned.
+ */
+__rte_experimental
+void *rte_memarea_alloc(struct rte_memarea *ma, uint32_t size);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Free memory to memarea.
+ *
+ * Free one memory region to the memarea.
+ *
+ * @param ma
+ *   The pointer of memarea.
+ * @param ptr
+ *   The pointer of memory region which need be freed.
+ */
+__rte_experimental
+void rte_memarea_free(struct rte_memarea *ma, void *ptr);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Update memory's refcnt.
+ *
+ * Update one memory region's refcnt.
+ *
+ * @param ma
+ *   The pointer of memarea.
+ * @param ptr
+ *   The pointer of memory region which need be updated refcnt.
+ * @param value
+ *   The value which need be updated.
+ *   Note: it could be negative.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_experimental
+int rte_memarea_refcnt_update(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.
+ *
+ * @return
+ *   0 on success. Otherwise negative value is returned.
+ */
+__rte_experimental
+int rte_memarea_dump(struct rte_memarea *ma, FILE *f);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RTE_MEMAREA_H */
diff --git a/lib/memarea/version.map b/lib/memarea/version.map
new file mode 100644
index 0000000000..6d75f9f7c4
--- /dev/null
+++ b/lib/memarea/version.map
@@ -0,0 +1,16 @@
+EXPERIMENTAL {
+	global:
+
+	rte_memarea_alloc;
+	rte_memarea_create;
+	rte_memarea_destroy;
+	rte_memarea_dump;
+	rte_memarea_free;
+	rte_memarea_refcnt_update;
+
+	local: *;
+};
+
+INTERNAL {
+	local: *;
+};
diff --git a/lib/meson.build b/lib/meson.build
index c648f7d800..521a25d6c0 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -42,6 +42,7 @@ libraries = [
         'kni',
         'latencystats',
         'lpm',
+        'memarea',
         'member',
         'pcapng',
         'power',
-- 
2.33.0


^ permalink raw reply	[flat|nested] 222+ messages in thread