[1/8] memarea: introduce memory area library

Message ID 20220920034643.55476-2-fengchengwen@huawei.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series introduce memarea library |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

fengchengwen Sept. 20, 2022, 3:46 a.m. UTC
  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 features 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.

This patch provides create/destroy API.

Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
---
 MAINTAINERS                            |   5 +
 doc/api/doxy-api-index.md              |   3 +-
 doc/api/doxy-api.conf.in               |   1 +
 doc/guides/prog_guide/index.rst        |   1 +
 doc/guides/prog_guide/memarea_lib.rst  |  41 ++++++++
 doc/guides/rel_notes/release_22_11.rst |   6 ++
 lib/eal/include/rte_log.h              |   1 +
 lib/memarea/memarea_private.h          |  30 ++++++
 lib/memarea/meson.build                |  16 +++
 lib/memarea/rte_memarea.c              | 140 +++++++++++++++++++++++++
 lib/memarea/rte_memarea.h              | 131 +++++++++++++++++++++++
 lib/memarea/version.map                |  12 +++
 lib/meson.build                        |   1 +
 13 files changed, 387 insertions(+), 1 deletion(-)
 create mode 100644 doc/guides/prog_guide/memarea_lib.rst
 create mode 100644 lib/memarea/memarea_private.h
 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
  

Comments

Dmitry Kozlyuk Sept. 20, 2022, 11:30 a.m. UTC | #1
2022-09-20 03:46 (UTC+0000), Chengwen Feng:
> 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 features are as follows:
> a) it facilitate alloc and free of memory with low overhead.

Yet, the overhead is 64B per element, just like rte_malloc.

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

Are you sure refcnt should be in this library?
I've expressed my concerns here:

https://inbox.dpdk.org/dev/CAEYuUWBpC-9dCqKJ0LZi6RkCUwyeYEghLRBMBUBtUx4Ljg+pAQ@mail.gmail.com

There are more unanswered questions in that mail,
it would be good to clarify them before reviewing these patches
in order to understand all the intentions.

> +static int
> +memarea_check_param(const struct rte_memarea_param *init)
> +{
> +	size_t len;
> +
> +	len = strnlen(init->name, RTE_MEMAREA_NAMESIZE);
> +	if (len == 0 || len >= RTE_MEMAREA_NAMESIZE) {
> +		RTE_LOG(ERR, MEMAREA, "memarea name invalid!\n");
> +		return -EINVAL;
> +	}

Please check init->name == NULL first.

> +struct rte_memarea *
> +rte_memarea_create(const struct rte_memarea_param *init)
> +{
[...]
> +		RTE_LOG(ERR, MEMAREA, "malloc memarea management obj fail!\n");

In all error messages, it would be useful to provide details:
the name of the area, what size was requested, etc.

> +/**
> + * Memarea memory source.
> + */
> +enum rte_memarea_source {
> +	/** Memory source comes from system API (e.g. malloc). */
> +	RTE_MEMAREA_SOURCE_SYSTEM_API,
> +	/** Memory source comes from user-provided address. */
> +	RTE_MEMAREA_SOURCE_USER_ADDR,
> +	/** Memory source comes from user-provided memarea. */
> +	RTE_MEMAREA_SOURCE_USER_MEMAREA,
> +
> +	RTE_MEMAREA_SOURCE_BUTT

DPDK enumerations must not include an item to hold the element count,
because it is harmful for ABI (e.g. developers create arrays of this size
and when a new item is added in a new DPDK version, the array overflows).

If it's supposed to mean "the end of item list",
the proper word would be "last" or "max" BTW :)

> +};
> +
> +struct rte_memarea {
> +	void *private_data; /**< private management data pointer. */
> +};

Jerin and Stephen suggested to make the structure opaque,
i.e. only declare the struct and define it privately.
It would reduce ABI and simplify allocation.
Any justification to expose it?
  
Dmitry Kozlyuk Sept. 20, 2022, 11:31 a.m. UTC | #2
2022-09-20 14:30 (UTC+0300), Dmitry Kozlyuk:
> 2022-09-20 03:46 (UTC+0000), Chengwen Feng:
> > 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 features are as follows:
> > a) it facilitate alloc and free of memory with low overhead.  
> 
> Yet, the overhead is 64B per element, just like rte_malloc.

Disregard this one, rte_malloc overhead is 128B (2 cache lines).
  
fengchengwen Sept. 20, 2022, 12:06 p.m. UTC | #3
Hi Dmitry,

On 2022/9/20 19:30, Dmitry Kozlyuk wrote:
> 2022-09-20 03:46 (UTC+0000), Chengwen Feng:
>> 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 features are as follows:
>> a) it facilitate alloc and free of memory with low overhead.
> Yet, the overhead is 64B per element, just like rte_malloc.
>
>> b) it provides refcnt feature which could be useful in some scenes.
> Are you sure refcnt should be in this library?
> I've expressed my concerns here:
>
> https://inbox.dpdk.org/dev/CAEYuUWBpC-9dCqKJ0LZi6RkCUwyeYEghLRBMBUBtUx4Ljg+pAQ@mail.gmail.com
>
> There are more unanswered questions in that mail,
> it would be good to clarify them before reviewing these patches
> in order to understand all the intentions.

Sorry to forgot reply it.

We have the following scene which used refcnt:

     nic-rx  ->  decoder ->  process

                                    |

                                   ->  recording

as above show, the process and recording module both use the decoder's 
output, the are just reader.

so in this case, the refcnt is useful.

>
>> +static int
>> +memarea_check_param(const struct rte_memarea_param *init)
>> +{
>> +	size_t len;
>> +
>> +	len = strnlen(init->name, RTE_MEMAREA_NAMESIZE);
>> +	if (len == 0 || len >= RTE_MEMAREA_NAMESIZE) {
>> +		RTE_LOG(ERR, MEMAREA, "memarea name invalid!\n");
>> +		return -EINVAL;
>> +	}
> Please check init->name == NULL first.

No need checking because name is an array.

Maybe I should check init == NULL here.

>
>> +struct rte_memarea *
>> +rte_memarea_create(const struct rte_memarea_param *init)
>> +{
> [...]
>> +		RTE_LOG(ERR, MEMAREA, "malloc memarea management obj fail!\n");
> In all error messages, it would be useful to provide details:
> the name of the area, what size was requested, etc.

will fix in v2.

>
>> +/**
>> + * Memarea memory source.
>> + */
>> +enum rte_memarea_source {
>> +	/** Memory source comes from system API (e.g. malloc). */
>> +	RTE_MEMAREA_SOURCE_SYSTEM_API,
>> +	/** Memory source comes from user-provided address. */
>> +	RTE_MEMAREA_SOURCE_USER_ADDR,
>> +	/** Memory source comes from user-provided memarea. */
>> +	RTE_MEMAREA_SOURCE_USER_MEMAREA,
>> +
>> +	RTE_MEMAREA_SOURCE_BUTT
> DPDK enumerations must not include an item to hold the element count,
> because it is harmful for ABI (e.g. developers create arrays of this size
> and when a new item is added in a new DPDK version, the array overflows).
>
> If it's supposed to mean "the end of item list",
> the proper word would be "last" or "max" BTW :)
will fix in v2
>
>> +};
>> +
>> +struct rte_memarea {
>> +	void *private_data; /**< private management data pointer. */
>> +};
> Jerin and Stephen suggested to make the structure opaque,
> i.e. only declare the struct and define it privately.
> It would reduce ABI and simplify allocation.
> Any justification to expose it?

do you mean the rte_memarea just void * ? it just (void 
*)(memarea_private *)priv ?

It's another popular type to impl ABI compatiable.

It's more simpler, will fix in v2
  

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 32ffdd1a61..92e77f1318 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1557,6 +1557,11 @@  F: app/test/test_lpm*
 F: app/test/test_func_reentrancy.c
 F: app/test/test_xmmt_ops.h
 
+Memarea - EXPERIMENTAL
+M: Chengwen Feng <fengchengwen@huawei.com>
+F: lib/memarea
+F: doc/guides/prog_guide/memarea_lib.rst
+
 Membership - EXPERIMENTAL
 M: Yipeng Wang <yipeng1.wang@intel.com>
 M: Sameh Gobriel <sameh.gobriel@intel.com>
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 186a258be4..25dbef0b68 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -64,7 +64,8 @@  The public API headers are grouped by topics:
   [memzone](@ref rte_memzone.h),
   [mempool](@ref rte_mempool.h),
   [malloc](@ref rte_malloc.h),
-  [memcpy](@ref rte_memcpy.h)
+  [memcpy](@ref rte_memcpy.h),
+  [memarea](@ref rte_memarea.h)
 
 - **timers**:
   [cycles](@ref rte_cycles.h),
diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index 608494a7c0..bdc5d2b0d5 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -55,6 +55,7 @@  INPUT                   = @TOPDIR@/doc/api/doxy-api-index.md \
                           @TOPDIR@/lib/latencystats \
                           @TOPDIR@/lib/lpm \
                           @TOPDIR@/lib/mbuf \
+                          @TOPDIR@/lib/memarea \
                           @TOPDIR@/lib/member \
                           @TOPDIR@/lib/mempool \
                           @TOPDIR@/lib/meter \
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 8564883018..e9015d65e3 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -37,6 +37,7 @@  Programmer's Guide
     hash_lib
     toeplitz_hash_lib
     efd_lib
+    memarea_lib
     member_lib
     lpm_lib
     lpm6_lib
diff --git a/doc/guides/prog_guide/memarea_lib.rst b/doc/guides/prog_guide/memarea_lib.rst
new file mode 100644
index 0000000000..1979f0a12c
--- /dev/null
+++ b/doc/guides/prog_guide/memarea_lib.rst
@@ -0,0 +1,41 @@ 
+..  SPDX-License-Identifier: BSD-3-Clause
+    Copyright(c) 2022 HiSilicon Limited
+
+Memarea Library
+===============
+
+Introduction
+------------
+
+The memarea library provides an allocator of variable-size objects, it is
+oriented towards the application layer, which could provides 'region-based
+memory management' function [1].
+
+The main features are as follows:
+
+* It facilitate alloc and free of memory with low overhead.
+
+* It's memory source could comes from: 1) System API: e.g. malloc/memalign in
+  C library. 2) User provided address: it can be from the rte_malloc API series
+  or extended memory as long as it is available. 3) User provided memarea: it
+  can be from another memarea.
+
+* The default aligement size is ``RTE_CACHE_LINE_SIZE``.
+
+* It provides refcnt feature which could be useful in some scenes.
+
+* It supports MT-safe as long as it's specified at creation time.
+
+Library API Overview
+--------------------
+
+The ``rte_memarea_create()`` function is used to create a memarea object, the
+function returns the pointer to the created memarea or ``NULL`` if the creation
+failed.
+
+The ``rte_memarea_destroy()`` function is used to destroy a memarea object.
+
+Reference
+---------
+
+[1] https://en.wikipedia.org/wiki/Region-based_memory_management
diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index 8c021cf050..1cf522132c 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -55,6 +55,12 @@  New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added memarea library.**
+
+  The memarea library is an allocator of variable-size objects, it is oriented
+  towards the application layer, which could provides 'region-based memory
+  management' function.
+
 
 Removed Items
 -------------
diff --git a/lib/eal/include/rte_log.h b/lib/eal/include/rte_log.h
index 25ce42cdfc..708f3a39dd 100644
--- a/lib/eal/include/rte_log.h
+++ b/lib/eal/include/rte_log.h
@@ -48,6 +48,7 @@  extern "C" {
 #define RTE_LOGTYPE_EFD       18 /**< Log related to EFD. */
 #define RTE_LOGTYPE_EVENTDEV  19 /**< Log related to eventdev. */
 #define RTE_LOGTYPE_GSO       20 /**< Log related to GSO. */
+#define RTE_LOGTYPE_MEMAREA   21 /**< Log related to memarea. */
 
 /* these log types can be used in an application */
 #define RTE_LOGTYPE_USER1     24 /**< User-defined log type 1. */
diff --git a/lib/memarea/memarea_private.h b/lib/memarea/memarea_private.h
new file mode 100644
index 0000000000..94931b46e9
--- /dev/null
+++ b/lib/memarea/memarea_private.h
@@ -0,0 +1,30 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 HiSilicon Limited
+ */
+
+#ifndef MEMAREA_PRIVATE_H
+#define MEMAREA_PRIVATE_H
+
+#include <rte_memarea.h>
+
+#define MEMAREA_FREE_ELEM_COOKIE	0xFFFFFFFF
+
+struct memarea_elem {
+	size_t   size;
+	uint32_t cookie;
+	int32_t  refcnt; /* Non-zero indicates that it has been allocated */
+	TAILQ_ENTRY(memarea_elem) elem_node;
+	TAILQ_ENTRY(memarea_elem) free_node;
+} __rte_cache_aligned;
+
+TAILQ_HEAD(memarea_elem_list, memarea_elem);
+
+struct memarea_private {
+	struct rte_memarea_param init;
+	rte_spinlock_t           lock;
+	void                    *area_addr;
+	struct memarea_elem_list elem_list;
+	struct memarea_elem_list free_list;
+} __rte_cache_aligned;
+
+#endif /* MEMAREA_PRIVATE_H */
diff --git a/lib/memarea/meson.build b/lib/memarea/meson.build
new file mode 100644
index 0000000000..0a74fb4cd1
--- /dev/null
+++ b/lib/memarea/meson.build
@@ -0,0 +1,16 @@ 
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2022 HiSilicon Limited
+
+if is_windows
+    build = false
+    reason = 'not supported on Windows'
+    subdir_done()
+endif
+
+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..3f535d315f
--- /dev/null
+++ b/lib/memarea/rte_memarea.c
@@ -0,0 +1,140 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2022 HiSilicon Limited
+ */
+
+#include <stdio.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_memarea.h>
+#include <rte_spinlock.h>
+
+#include "memarea_private.h"
+
+static int
+memarea_check_param(const struct rte_memarea_param *init)
+{
+	size_t len;
+
+	len = strnlen(init->name, RTE_MEMAREA_NAMESIZE);
+	if (len == 0 || len >= RTE_MEMAREA_NAMESIZE) {
+		RTE_LOG(ERR, MEMAREA, "memarea name invalid!\n");
+		return -EINVAL;
+	}
+
+	if (init->source >= RTE_MEMAREA_SOURCE_BUTT) {
+		RTE_LOG(ERR, MEMAREA, "memarea source invalid!\n");
+		return -EINVAL;
+	}
+
+	if (init->total_sz <= sizeof(struct memarea_elem)) {
+		RTE_LOG(ERR, MEMAREA, "memarea total size invalid!\n");
+		return -EINVAL;
+	}
+
+	if (init->source == RTE_MEMAREA_SOURCE_USER_ADDR && init->user_addr == NULL) {
+		RTE_LOG(ERR, MEMAREA, "memarea user provided addr invalid!\n");
+		return -EINVAL;
+	}
+
+	if (init->source == RTE_MEMAREA_SOURCE_USER_ADDR &&
+	    ((uintptr_t)init->user_addr & (RTE_CACHE_LINE_SIZE - 1))) {
+		RTE_LOG(ERR, MEMAREA, "memarea user provided addr align invalid!\n");
+		return -EINVAL;
+	}
+
+	if (init->source == RTE_MEMAREA_SOURCE_USER_MEMAREA && init->user_memarea == NULL) {
+		RTE_LOG(ERR, MEMAREA, "memarea user provided memarea invalid!\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void *
+memarea_alloc_from_system_api(size_t size)
+{
+	void *ptr = NULL;
+	int ret;
+
+	ret = posix_memalign(&ptr, RTE_CACHE_LINE_SIZE, size);
+	if (ret)
+		return NULL;
+	return ptr;
+}
+
+static void *
+memarea_alloc_area(const struct rte_memarea_param *init)
+{
+	void *ptr = NULL;
+
+	if (init->source == RTE_MEMAREA_SOURCE_SYSTEM_API)
+		ptr = memarea_alloc_from_system_api(init->total_sz);
+	else if (init->source == RTE_MEMAREA_SOURCE_USER_ADDR)
+		ptr = init->user_addr;
+
+	if (ptr == NULL)
+		RTE_LOG(ERR, MEMAREA, "memarea alloc memory area fail!\n");
+
+	return ptr;
+}
+
+struct rte_memarea *
+rte_memarea_create(const struct rte_memarea_param *init)
+{
+	struct memarea_private *priv;
+	struct memarea_elem *elem;
+	struct rte_memarea *ma;
+	void *addr;
+	int ret;
+
+	ret = memarea_check_param(init);
+	if (ret)
+		return NULL;
+
+	addr = memarea_alloc_area(init);
+	if (addr == NULL)
+		return NULL;
+
+	ma = rte_zmalloc(NULL, sizeof(struct rte_memarea), RTE_CACHE_LINE_SIZE);
+	priv = rte_zmalloc(NULL, sizeof(struct memarea_private), RTE_CACHE_LINE_SIZE);
+	if (ma == NULL || priv == NULL) {
+		RTE_LOG(ERR, MEMAREA, "malloc memarea management obj fail!\n");
+		rte_free(ma);
+		rte_free(priv);
+		return NULL;
+	}
+
+	ma->private_data = priv;
+	priv->init = *init;
+	rte_spinlock_init(&priv->lock);
+	TAILQ_INIT(&priv->elem_list);
+	TAILQ_INIT(&priv->free_list);
+	priv->area_addr = addr;
+	elem = addr;
+	elem->size = init->total_sz - sizeof(struct memarea_elem);
+	elem->cookie = MEMAREA_FREE_ELEM_COOKIE;
+	elem->refcnt = 0;
+	TAILQ_INSERT_TAIL(&priv->elem_list, elem, elem_node);
+	TAILQ_INSERT_TAIL(&priv->free_list, elem, free_node);
+
+	return ma;
+}
+
+static void
+memarea_free_area(struct memarea_private *priv)
+{
+	if (priv->init.source == RTE_MEMAREA_SOURCE_SYSTEM_API)
+		free(priv->area_addr);
+}
+
+void
+rte_memarea_destroy(struct rte_memarea *ma)
+{
+	if (ma == NULL)
+		return;
+	memarea_free_area(ma->private_data);
+	rte_free(ma->private_data);
+	rte_free(ma);
+}
diff --git a/lib/memarea/rte_memarea.h b/lib/memarea/rte_memarea.h
new file mode 100644
index 0000000000..ddca0a47e2
--- /dev/null
+++ b/lib/memarea/rte_memarea.h
@@ -0,0 +1,131 @@ 
+/* 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's memory source could comes from:
+ *      1) System API: malloc/memalign in C library.
+ *      2) User provided address: it can be from the rte_malloc API series
+ *         or extended memory as long as it is available. The address must be
+ *         aligned to RTE_CACHE_LINE_SIZE.
+ *      3) User provided memarea: it can be from another memarea. So we can
+ *         build the following memory management structure:
+ *         \code{.unparsed}
+ *                           -------------
+ *                           | memarea-1 |
+ *                           -------------
+ *                                 |
+ *                                 v
+ *                  ------------------------------
+ *                  |               |            |
+ *                  v               v            v
+ *            -------------   -------------   -------
+ *            | memarea-2 |   | memarea-3 |   | obj |
+ *            -------------   -------------   -------
+ *         \endcode
+ *   c) The default alignment size is RTE_CACHE_LINE_SIZE.
+ *   d) It provides refcnt feature which could be useful in some scenes.
+ *   e) It supports MT-safe as long as it's specified at creation time. If not
+ *      specified, all the functions of the memarea API are lock-free, and
+ *      assume to not be invoked in parallel on different logical cores to work
+ *      on the same memarea object.
+ */
+
+#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 system API (e.g. malloc). */
+	RTE_MEMAREA_SOURCE_SYSTEM_API,
+	/** Memory source comes from user-provided address. */
+	RTE_MEMAREA_SOURCE_USER_ADDR,
+	/** Memory source comes from user-provided memarea. */
+	RTE_MEMAREA_SOURCE_USER_MEMAREA,
+
+	RTE_MEMAREA_SOURCE_BUTT
+};
+
+struct rte_memarea {
+	void *private_data; /**< private management data pointer. */
+};
+
+struct rte_memarea_param {
+	char name[RTE_MEMAREA_NAMESIZE]; /**< Name of memarea. */
+	enum rte_memarea_source source;  /**< Memory source of memarea. */
+	size_t total_sz;                 /**< total size (bytes) of memarea. */
+	/** Indicates whether the memarea API should be MT-safe. */
+	uint32_t mt_safe : 1;
+	union {
+		/** User provided address, this field is valid only when the
+		 * source is set to be RTE_MEMAREA_SOURCE_USER_ADDR.
+		 * Note: the provided address must align at least
+		 * RTE_CACHE_LINE_SIZE.
+		 */
+		void *user_addr;
+		/** User provided memarea, this field is valid only when the
+		 * source is set to be RTE_MEMAREA_SOURCE_USER_MEMAREA.
+		 */
+		struct rte_memarea *user_memarea;
+	};
+};
+
+/**
+ * @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.
+ */
+__rte_experimental
+void rte_memarea_destroy(struct rte_memarea *ma);
+
+#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..f36a04d7cf
--- /dev/null
+++ b/lib/memarea/version.map
@@ -0,0 +1,12 @@ 
+EXPERIMENTAL {
+	global:
+
+	rte_memarea_create;
+	rte_memarea_destroy;
+
+	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',