get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/129611/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 129611,
    "url": "http://patches.dpdk.org/api/patches/129611/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20230718024006.2154-2-fengchengwen@huawei.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20230718024006.2154-2-fengchengwen@huawei.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230718024006.2154-2-fengchengwen@huawei.com",
    "date": "2023-07-18T02:40:01",
    "name": "[v17,1/6] memarea: introduce memarea library",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "771f22c6f048e2a04a08653e187b55dd50a9e1fc",
    "submitter": {
        "id": 2146,
        "url": "http://patches.dpdk.org/api/people/2146/?format=api",
        "name": "fengchengwen",
        "email": "fengchengwen@huawei.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20230718024006.2154-2-fengchengwen@huawei.com/mbox/",
    "series": [
        {
            "id": 28961,
            "url": "http://patches.dpdk.org/api/series/28961/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=28961",
            "date": "2023-07-18T02:40:06",
            "name": "introduce memarea library",
            "version": 17,
            "mbox": "http://patches.dpdk.org/series/28961/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/129611/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/129611/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 670B242EA1;\n\tTue, 18 Jul 2023 04:48:47 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 0013B42D3A;\n\tTue, 18 Jul 2023 04:48:27 +0200 (CEST)",
            "from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188])\n by mails.dpdk.org (Postfix) with ESMTP id 6F58A427E9\n for <dev@dpdk.org>; Tue, 18 Jul 2023 04:48:20 +0200 (CEST)",
            "from dggpeml100024.china.huawei.com (unknown [172.30.72.57])\n by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4R4jym3XDQzVjfH;\n Tue, 18 Jul 2023 10:46:56 +0800 (CST)",
            "from localhost.localdomain (10.50.163.32) by\n dggpeml100024.china.huawei.com (7.185.36.115) with Microsoft SMTP Server\n (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id\n 15.1.2507.27; Tue, 18 Jul 2023 10:48:17 +0800"
        ],
        "From": "Chengwen Feng <fengchengwen@huawei.com>",
        "To": "<thomas@monjalon.net>, <david.marchand@redhat.com>",
        "CC": "<dev@dpdk.org>, <mb@smartsharesystems.com>, <anatoly.burakov@intel.com>,\n <dmitry.kozliuk@gmail.com>, <jerinjacobk@gmail.com>, <hofors@lysator.liu.se>,\n <stephen@networkplumber.org>",
        "Subject": "[PATCH v17 1/6] memarea: introduce memarea library",
        "Date": "Tue, 18 Jul 2023 02:40:01 +0000",
        "Message-ID": "<20230718024006.2154-2-fengchengwen@huawei.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20230718024006.2154-1-fengchengwen@huawei.com>",
        "References": "<20220721044648.6817-1-fengchengwen@huawei.com>\n <20230718024006.2154-1-fengchengwen@huawei.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"UTF-8\"",
        "Content-Transfer-Encoding": "8bit",
        "X-Originating-IP": "[10.50.163.32]",
        "X-ClientProxiedBy": "dggems705-chm.china.huawei.com (10.3.19.182) To\n dggpeml100024.china.huawei.com (7.185.36.115)",
        "X-CFilter-Loop": "Reflected",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "The memarea library is an allocator of variable-size object which based\non a memory region.\n\nThis patch provides rte_memarea_create() and rte_memarea_destroy() API.\n\nSigned-off-by: Chengwen Feng <fengchengwen@huawei.com>\nReviewed-by: Dongdong Liu <liudongdong3@huawei.com>\nAcked-by: Morten Brørup <mb@smartsharesystems.com>\nAcked-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n MAINTAINERS                            |   5 +\n doc/api/doxy-api-index.md              |   3 +-\n doc/api/doxy-api.conf.in               |   1 +\n doc/guides/prog_guide/index.rst        |   1 +\n doc/guides/prog_guide/memarea_lib.rst  |  48 ++++++\n doc/guides/rel_notes/release_23_07.rst |   6 +\n lib/memarea/memarea_private.h          | 116 ++++++++++++++\n lib/memarea/meson.build                |  12 ++\n lib/memarea/rte_memarea.c              | 208 +++++++++++++++++++++++++\n lib/memarea/rte_memarea.h              | 141 +++++++++++++++++\n lib/memarea/version.map                |  12 ++\n lib/meson.build                        |   1 +\n 12 files changed, 553 insertions(+), 1 deletion(-)\n create mode 100644 doc/guides/prog_guide/memarea_lib.rst\n create mode 100644 lib/memarea/memarea_private.h\n create mode 100644 lib/memarea/meson.build\n create mode 100644 lib/memarea/rte_memarea.c\n create mode 100644 lib/memarea/rte_memarea.h\n create mode 100644 lib/memarea/version.map",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 5bb8090ebe..9ca665219b 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -1613,6 +1613,11 @@ F: app/test/test_lpm*\n F: app/test/test_func_reentrancy.c\n F: app/test/test_xmmt_ops.h\n \n+Memarea - EXPERIMENTAL\n+M: Chengwen Feng <fengchengwen@huawei.com>\n+F: lib/memarea\n+F: doc/guides/prog_guide/memarea_lib.rst\n+\n Membership - EXPERIMENTAL\n M: Yipeng Wang <yipeng1.wang@intel.com>\n M: Sameh Gobriel <sameh.gobriel@intel.com>\ndiff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md\nindex 3bc8778981..5c32913f92 100644\n--- a/doc/api/doxy-api-index.md\n+++ b/doc/api/doxy-api-index.md\n@@ -65,7 +65,8 @@ The public API headers are grouped by topics:\n   [memzone](@ref rte_memzone.h),\n   [mempool](@ref rte_mempool.h),\n   [malloc](@ref rte_malloc.h),\n-  [memcpy](@ref rte_memcpy.h)\n+  [memcpy](@ref rte_memcpy.h),\n+  [memarea](@ref rte_memarea.h)\n \n - **timers**:\n   [cycles](@ref rte_cycles.h),\ndiff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in\nindex 1a4210b948..1f35d8483e 100644\n--- a/doc/api/doxy-api.conf.in\n+++ b/doc/api/doxy-api.conf.in\n@@ -54,6 +54,7 @@ INPUT                   = @TOPDIR@/doc/api/doxy-api-index.md \\\n                           @TOPDIR@/lib/latencystats \\\n                           @TOPDIR@/lib/lpm \\\n                           @TOPDIR@/lib/mbuf \\\n+                          @TOPDIR@/lib/memarea \\\n                           @TOPDIR@/lib/member \\\n                           @TOPDIR@/lib/mempool \\\n                           @TOPDIR@/lib/meter \\\ndiff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst\nindex d89cd3edb6..aa8eebe256 100644\n--- a/doc/guides/prog_guide/index.rst\n+++ b/doc/guides/prog_guide/index.rst\n@@ -38,6 +38,7 @@ Programmer's Guide\n     hash_lib\n     toeplitz_hash_lib\n     efd_lib\n+    memarea_lib\n     member_lib\n     lpm_lib\n     lpm6_lib\ndiff --git a/doc/guides/prog_guide/memarea_lib.rst b/doc/guides/prog_guide/memarea_lib.rst\nnew file mode 100644\nindex 0000000000..bf19090294\n--- /dev/null\n+++ b/doc/guides/prog_guide/memarea_lib.rst\n@@ -0,0 +1,48 @@\n+..  SPDX-License-Identifier: BSD-3-Clause\n+    Copyright(c) 2023 HiSilicon Limited\n+\n+Memarea Library\n+===============\n+\n+Introduction\n+------------\n+\n+The memarea library provides an allocator of variable-size objects, it is\n+oriented towards the application layer, providing 'region-based memory\n+management' function [1].\n+\n+The main features are as follows:\n+\n+* The memory region can be initialized from the following memory sources:\n+\n+  - HEAP: e.g. invoke ``rte_malloc_socket``.\n+\n+  - LIBC: e.g. invoke posix_memalign.\n+\n+  - Another memarea: it can be allocated from another memarea.\n+\n+* It supports MT-safe as long as it's specified at creation time.\n+\n+* The address returned by the allocator is align to 8B.\n+\n+Library API Overview\n+--------------------\n+\n+The ``rte_memarea_create()`` function is used to create a memarea, the function\n+returns the pointer to the created memarea or ``NULL`` if the creation failed.\n+\n+The ``rte_memarea_destroy()`` function is used to destroy a memarea.\n+\n+Debug Mode\n+----------\n+\n+In debug mode, cookies are added at the beginning and end of objects, it will\n+help debugging buffer overflows.\n+\n+Debug mode is disabled by default, but can be enabled by setting\n+``RTE_LIBRTE_MEMAREA_DEBUG`` in ``config/rte_config.h``.\n+\n+Reference\n+---------\n+\n+[1] https://en.wikipedia.org/wiki/Region-based_memory_management\ndiff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst\nindex d4af85b3ff..4034a9e9c0 100644\n--- a/doc/guides/rel_notes/release_23_07.rst\n+++ b/doc/guides/rel_notes/release_23_07.rst\n@@ -222,6 +222,12 @@ New Features\n \n   See the :doc:`../tools/dmaperf` for more details.\n \n+* **Added memarea library.**\n+\n+  The memarea library is an allocator of variable-size objects, it is oriented\n+  towards the application layer, providing 'region-based memory management'\n+  function.\n+\n \n Removed Items\n -------------\ndiff --git a/lib/memarea/memarea_private.h b/lib/memarea/memarea_private.h\nnew file mode 100644\nindex 0000000000..fd485bb7e7\n--- /dev/null\n+++ b/lib/memarea/memarea_private.h\n@@ -0,0 +1,116 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 HiSilicon Limited\n+ */\n+\n+#ifndef MEMAREA_PRIVATE_H\n+#define MEMAREA_PRIVATE_H\n+\n+#include <rte_memarea.h>\n+\n+#define MEMAREA_MINIMUM_TOTAL_SIZE\t1024\n+\n+#define MEMAREA_OBJECT_SIZE_ALIGN\t8\n+\n+#define MEMAREA_OBJECT_HEADER_AVAILABLE_COOKIE\t0xbeef1234beef1234ULL\n+#define MEMAREA_OBJECT_HEADER_ALLOCATED_COOKIE\t0x12345678abcdef12ULL\n+#define MEMAREA_OBJECT_TRAILER_COOKIE\t\t0xabcd1234abcd5678ULL\n+\n+/** Object cookie target status. */\n+enum {\n+\t/** Object is set to be available, but don't set trailer cookie. */\n+\tCOOKIE_TARGET_STATUS_AVAILABLE,\n+\t/** Object is set to be allocated, but don't set trailer cookie. */\n+\tCOOKIE_TARGET_STATUS_ALLOCATED,\n+\t/** object is new split, the header cookie will set to be available,\n+\t * the trailer cookie of the previous object will be set.\n+\t */\n+\tCOOKIE_TARGET_STATUS_NEW_AVAILABLE,\n+\t/** object is new split, the header cookie will set to be allocated,\n+\t * the trailer cookie of the previous object will be set.\n+\t */\n+\tCOOKIE_TARGET_STATUS_NEW_ALLOCATED,\n+\t/** Object is to be merged, it will no longer exist. the header cookie\n+\t * is cleared and the trailer cookie of the previous object is cleared.\n+\t */\n+\tCOOKIE_TARGET_STATUS_CLEARED,\n+};\n+\n+/** Object cookie expect status. */\n+enum {\n+\t/** Object is supposed to be available. */\n+\tCOOKIE_EXPECT_STATUS_AVAILABLE,\n+\t/** Object is supposed to be allocated. */\n+\tCOOKIE_EXPECT_STATUS_ALLOCATED,\n+\t/** Object is supposed to be valid (available or allocated). */\n+\tCOOKIE_EXPECT_STATUS_VALID,\n+};\n+\n+#define MEMAREA_OBJECT_IS_ALLOCATED(hdr)\t(TAILQ_NEXT((hdr), avail_next) == (void *)-1)\n+#define MEMAREA_OBJECT_MARK_ALLOCATED(hdr)\t(TAILQ_NEXT((hdr), avail_next) = (void *)-1)\n+\n+#ifdef RTE_LIBRTE_MEMAREA_DEBUG\n+#define MEMAREA_OBJECT_GET_SIZE(hdr) \\\n+\t\t((uintptr_t)TAILQ_NEXT((hdr), obj_next) - (uintptr_t)(hdr) - \\\n+\t\t sizeof(struct memarea_objhdr) - sizeof(struct memarea_objtlr))\n+#else\n+#define MEMAREA_OBJECT_GET_SIZE(hdr) \\\n+\t\t((uintptr_t)TAILQ_NEXT((hdr), obj_next) - (uintptr_t)(hdr) - \\\n+\t\t sizeof(struct memarea_objhdr))\n+#endif\n+\n+struct memarea_objhdr {\n+\t/** The obj_next will form obj_list. */\n+\tTAILQ_ENTRY(memarea_objhdr) obj_next;\n+\t/** If the object is available, the avail_next will link in avail_list.\n+\t * If the object has been allocated, the avail_next.tqe_next is -1.\n+\t */\n+\tTAILQ_ENTRY(memarea_objhdr) avail_next;\n+#ifdef RTE_LIBRTE_MEMAREA_DEBUG\n+\tuint64_t                    cookie; /**< Debug cookie */\n+#endif\n+};\n+\n+#ifdef RTE_LIBRTE_MEMAREA_DEBUG\n+struct memarea_objtlr {\n+\tuint64_t cookie; /**< Debug cookie */\n+};\n+#endif\n+\n+TAILQ_HEAD(memarea_objhdr_list, memarea_objhdr);\n+\n+struct rte_memarea {\n+\tstruct rte_memarea_param   init;\n+\trte_spinlock_t             lock;\n+\tvoid                      *area_base;\n+\tstruct memarea_objhdr     *guard_hdr;\n+\t/** The obj_list is an address ascending ordered linked list:\n+\t *             ----------------------               --------------\n+\t *             |      object-1      |               |  object-1  |\n+\t * obj_list -> |~~~~~~~~~~~~~~~~~~~~|  data-region  |~~~~~~~~~~~~|\n+\t *        ---> | tailq | hdr-cookie |               | tlr-cookie |\n+\t *        |    ----------------------               --------------\n+\t *        |\n+\t *        |    ----------------------               --------------\n+\t *        |    |      object-2      |               |  object-2  |\n+\t *        ---> |~~~~~~~~~~~~~~~~~~~~|  data-region  |~~~~~~~~~~~~|\n+\t *        ---> | tailq | hdr-cookie |               | tlr-cookie |\n+\t *        |     ----------------------               --------------\n+\t *        ...\n+\t *        ...  more objects.\n+\t *        ...\n+\t *        |    ----------------------\n+\t *        |    |    object-guard    |\n+\t *        ---> |~~~~~~~~~~~~~~~~~~~~|\n+\t *             | tailq | hdr-cookie |\n+\t *             ----------------------\n+\t * Note: the last object is the guard object, which has no data-region\n+\t *       and no trailer cookie.\n+\t **/\n+\tstruct memarea_objhdr_list obj_list;\n+\t/** The avail_list is an unordered linked list. This list will hold the\n+\t * objects which are available(means can be used to allocate).\n+\t */\n+\tstruct memarea_objhdr_list avail_list;\n+} __rte_cache_aligned;\n+\n+#endif /* MEMAREA_PRIVATE_H */\ndiff --git a/lib/memarea/meson.build b/lib/memarea/meson.build\nnew file mode 100644\nindex 0000000000..48499626fd\n--- /dev/null\n+++ b/lib/memarea/meson.build\n@@ -0,0 +1,12 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2023 HiSilicon Limited\n+\n+sources = files(\n+        'rte_memarea.c',\n+)\n+headers = files(\n+        'rte_memarea.h',\n+)\n+deps += []\n+\n+annotate_locks = false\ndiff --git a/lib/memarea/rte_memarea.c b/lib/memarea/rte_memarea.c\nnew file mode 100644\nindex 0000000000..ea9067fb35\n--- /dev/null\n+++ b/lib/memarea/rte_memarea.c\n@@ -0,0 +1,208 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 HiSilicon Limited\n+ */\n+\n+#include <stdio.h>\n+#include <stdlib.h>\n+\n+#include <rte_common.h>\n+#include <rte_errno.h>\n+#include <rte_log.h>\n+#include <rte_malloc.h>\n+#include <rte_spinlock.h>\n+\n+#include \"rte_memarea.h\"\n+#include \"memarea_private.h\"\n+\n+RTE_LOG_REGISTER_DEFAULT(rte_memarea_logtype, INFO);\n+#define RTE_MEMAREA_LOG(level, fmt, args...) \\\n+\trte_log(RTE_LOG_ ## level, rte_memarea_logtype, \\\n+\t\t\"MEMAREA: %s(): \" fmt \"\\n\", __func__, ## args)\n+\n+static int\n+memarea_check_param(const struct rte_memarea_param *init)\n+{\n+\tsize_t len;\n+\n+\tif (init == NULL) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"init param is NULL!\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tlen = strnlen(init->name, RTE_MEMAREA_NAMESIZE);\n+\tif (len == 0 || len >= RTE_MEMAREA_NAMESIZE) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"name size: %zu invalid!\", len);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (init->source != RTE_MEMAREA_SOURCE_HEAP &&\n+\t    init->source != RTE_MEMAREA_SOURCE_LIBC &&\n+\t    init->source != RTE_MEMAREA_SOURCE_MEMAREA) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"%s source: %d not supported!\",\n+\t\t\tinit->name, init->source);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (init->total_sz < MEMAREA_MINIMUM_TOTAL_SIZE) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"%s total-size: %zu too small!\",\n+\t\t\tinit->name, init->total_sz);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (init->source == RTE_MEMAREA_SOURCE_MEMAREA && init->ma.src == NULL) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"%s source memarea is NULL!\", init->name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (init->alg != RTE_MEMAREA_ALGORITHM_NEXTFIT) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"%s algorithm: %d not supported!\",\n+\t\t\tinit->name, init->alg);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (init->reserved_bits != 0 || init->reserved_64s[0] != 0 ||\n+\t    init->reserved_64s[1] != 0) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"%s reserved field not zero!\", init->name);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void *\n+memarea_alloc_from_libc(size_t size)\n+{\n+#ifdef RTE_EXEC_ENV_WINDOWS\n+\treturn _aligned_malloc(size, RTE_CACHE_LINE_SIZE);\n+#else\n+\tvoid *ptr = NULL;\n+\tint ret;\n+\tret = posix_memalign(&ptr, RTE_CACHE_LINE_SIZE, size);\n+\tif (ret != 0)\n+\t\treturn NULL;\n+\treturn ptr;\n+ #endif\n+}\n+\n+static void *\n+memarea_alloc_area(const struct rte_memarea_param *init)\n+{\n+\tvoid *ptr = NULL;\n+\n+\tif (init->source == RTE_MEMAREA_SOURCE_HEAP)\n+\t\tptr = rte_malloc_socket(NULL, init->total_sz, RTE_CACHE_LINE_SIZE,\n+\t\t\t\t\tinit->heap.socket_id);\n+\telse if (init->source == RTE_MEMAREA_SOURCE_LIBC)\n+\t\tptr = memarea_alloc_from_libc(init->total_sz);\n+\n+\treturn ptr;\n+}\n+\n+static void\n+memarea_free_area(const struct rte_memarea_param *init, void *ptr)\n+{\n+\tif (init->source == RTE_MEMAREA_SOURCE_HEAP)\n+\t\trte_free(ptr);\n+\telse if (init->source == RTE_MEMAREA_SOURCE_LIBC)\n+\t\tfree(ptr);\n+}\n+\n+static inline void\n+memarea_set_cookie(struct memarea_objhdr *hdr, int status)\n+{\n+#ifdef RTE_LIBRTE_MEMAREA_DEBUG\n+\tstruct memarea_objtlr *tlr;\n+\n+\tif (status == 0) {\n+\t\thdr->cookie = MEMAREA_OBJECT_HEADER_AVAILABLE_COOKIE;\n+\t} else if (status == 1) {\n+\t\thdr->cookie = MEMAREA_OBJECT_HEADER_ALLOCATED_COOKIE;\n+\t} else if (status == 2) {\n+\t\thdr->cookie = MEMAREA_OBJECT_HEADER_AVAILABLE_COOKIE;\n+\t\ttlr = RTE_PTR_SUB(hdr, sizeof(struct memarea_objtlr));\n+\t\ttlr->cookie = MEMAREA_OBJECT_TRAILER_COOKIE;\n+\t} else if (status == 3) {\n+\t\thdr->cookie = MEMAREA_OBJECT_HEADER_ALLOCATED_COOKIE;\n+\t\ttlr = RTE_PTR_SUB(hdr, sizeof(struct memarea_objtlr));\n+\t\ttlr->cookie = MEMAREA_OBJECT_TRAILER_COOKIE;\n+\t} else if (status == 4) {\n+\t\thdr->cookie = 0;\n+\t\ttlr = RTE_PTR_SUB(hdr, sizeof(struct memarea_objtlr));\n+\t\ttlr->cookie = 0;\n+\t}\n+#else\n+\tRTE_SET_USED(hdr);\n+\tRTE_SET_USED(status);\n+#endif\n+}\n+\n+struct rte_memarea *\n+rte_memarea_create(const struct rte_memarea_param *init)\n+{\n+\tstruct memarea_objhdr *hdr, *guard_hdr;\n+\tstruct rte_memarea *ma;\n+\tsize_t align_sz;\n+\tvoid *ptr;\n+\tint ret;\n+\n+\t/** 1st: check parameter valid. */\n+\tret = memarea_check_param(init);\n+\tif (ret != 0) {\n+\t\trte_errno = -ret;\n+\t\treturn NULL;\n+\t}\n+\n+\t/** 2nd: alloc the memarea data region. */\n+\tptr = memarea_alloc_area(init);\n+\tif (ptr == NULL) {\n+\t\tRTE_MEMAREA_LOG(ERR, \"%s alloc memory area fail!\", init->name);\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\n+\t/** 3rd: alloc the memare management struct. */\n+\tma = rte_zmalloc(NULL, sizeof(struct rte_memarea), RTE_CACHE_LINE_SIZE);\n+\tif (ma == NULL) {\n+\t\tmemarea_free_area(init, ptr);\n+\t\tRTE_MEMAREA_LOG(ERR, \"%s alloc management object fail!\", init->name);\n+\t\trte_errno = ENOMEM;\n+\t\treturn NULL;\n+\t}\n+\n+\t/** 4th: backup init parameter, initialize the lock and list. */\n+\tma->init = *init;\n+\trte_spinlock_init(&ma->lock);\n+\tTAILQ_INIT(&ma->obj_list);\n+\tTAILQ_INIT(&ma->avail_list);\n+\n+\t/** 5th: initialize the first object and last guard object. */\n+\thdr = ptr;\n+\talign_sz = RTE_ALIGN_FLOOR(init->total_sz, MEMAREA_OBJECT_SIZE_ALIGN);\n+\tguard_hdr = RTE_PTR_ADD(ptr, align_sz - sizeof(struct memarea_objhdr));\n+\tma->area_base = ptr;\n+\tma->guard_hdr = guard_hdr;\n+\n+\t/** 5.1: hook the first object to both obj_list and avail_list. */\n+\tTAILQ_INSERT_TAIL(&ma->obj_list, hdr, obj_next);\n+\tTAILQ_INSERT_TAIL(&ma->avail_list, hdr, avail_next);\n+\tmemarea_set_cookie(hdr, COOKIE_TARGET_STATUS_AVAILABLE);\n+\n+\t/** 5.2: hook the guard object to only obj_list. */\n+\tmemset(guard_hdr, 0, sizeof(struct memarea_objhdr));\n+\tTAILQ_INSERT_AFTER(&ma->obj_list, hdr, guard_hdr, obj_next);\n+\tMEMAREA_OBJECT_MARK_ALLOCATED(guard_hdr);\n+\tmemarea_set_cookie(guard_hdr, COOKIE_TARGET_STATUS_NEW_ALLOCATED);\n+\n+\treturn ma;\n+}\n+\n+void\n+rte_memarea_destroy(struct rte_memarea *ma)\n+{\n+\tif (ma == NULL) {\n+\t\trte_errno = EINVAL;\n+\t\treturn;\n+\t}\n+\tmemarea_free_area(&ma->init, ma->area_base);\n+\trte_free(ma);\n+}\ndiff --git a/lib/memarea/rte_memarea.h b/lib/memarea/rte_memarea.h\nnew file mode 100644\nindex 0000000000..1d4381efd7\n--- /dev/null\n+++ b/lib/memarea/rte_memarea.h\n@@ -0,0 +1,141 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 HiSilicon Limited\n+ */\n+\n+#ifndef RTE_MEMAREA_H\n+#define RTE_MEMAREA_H\n+\n+/**\n+ * @file\n+ * RTE Memarea.\n+ *\n+ * The memarea is an allocator of variable-size object which based on a memory\n+ * region. It has the following features:\n+ *\n+ * - The memory region can be initialized from the following memory sources:\n+ *   1. HEAP: e.g. invoke rte_malloc_xxx family.\n+ *   2. LIBC: e.g. invoke posix_memalign.\n+ *   3. Another memarea: it can be allocated from another memarea.\n+ *\n+ * - It supports MT-safe as long as it's specified at creation time. If not\n+ *   specified, all the functions of the memarea API are lock-free, and assume\n+ *   to not be invoked in parallel on different logical cores to work on the\n+ *   same memarea.\n+ *\n+ * - The address returned by the allocator is align to 8B.\n+ *\n+ * @note The current implementation is a minimum set and does not support\n+ * multiple-process.\n+ */\n+\n+#include <stdbool.h>\n+#include <stdint.h>\n+#include <stdio.h>\n+\n+#include <rte_compat.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#define RTE_MEMAREA_NAMESIZE\t64\n+\n+/**\n+ * Memarea memory source.\n+ */\n+enum rte_memarea_source {\n+\t/** Memory source comes from rte_malloc_xxx memory. */\n+\tRTE_MEMAREA_SOURCE_HEAP,\n+\t/** Memory source comes from libc. */\n+\tRTE_MEMAREA_SOURCE_LIBC,\n+\t/** Memory source comes from another memarea. */\n+\tRTE_MEMAREA_SOURCE_MEMAREA,\n+};\n+\n+/**\n+ * Memarea memory management algorithm.\n+ */\n+enum rte_memarea_algorithm {\n+\t/** The default management algorithm is a variant of the next fit\n+\t * algorithm. It uses a free-list to apply for memory and uses an\n+\t * object-list in ascending order of address to support merging\n+\t * upon free.\n+\t */\n+\tRTE_MEMAREA_ALGORITHM_NEXTFIT,\n+};\n+\n+struct rte_memarea;\n+\n+/**\n+ * Memarea creation parameters.\n+ */\n+struct rte_memarea_param {\n+\tchar name[RTE_MEMAREA_NAMESIZE]; /**< Name of memarea. */\n+\tenum rte_memarea_source source;  /**< Memory source of memarea. */\n+\tenum rte_memarea_algorithm alg;  /**< Memory management algorithm. */\n+\t/** Total size (bytes) of memarea, it should not be less be 1024. */\n+\tsize_t total_sz;\n+\t/** Indicates whether the memarea API should be MT-safe. */\n+\tuint32_t mt_safe : 1;\n+\t/** Reserved for future field, should be initialized to zero. */\n+\tuint32_t reserved_bits : 31;\n+\tunion {\n+\t\t/** The initialization parameters if the source is set to be\n+\t\t * RTE_MEMAREA_SOURCE_HEAP.\n+\t\t */\n+\t\tstruct {\n+\t\t\t/** Socket from which to apply for memarea's memory. */\n+\t\t\tint socket_id;\n+\t\t} heap;\n+\t\t/** The initialization parameters if the source is set to be\n+\t\t * RTE_MEMAREA_SOURCE_MEMAREA.\n+\t\t */\n+\t\tstruct {\n+\t\t\t/** Source memarea which to apply for this memarea's\n+\t\t\t * memory from.\n+\t\t\t */\n+\t\t\tstruct rte_memarea *src;\n+\t\t} ma;\n+\t};\n+\t/** Reserved for future fields, should be initialized to zero. */\n+\tuint64_t reserved_64s[2];\n+};\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Create memarea.\n+ *\n+ * Create one new memarea.\n+ *\n+ * @param init\n+ *   The init parameter of memarea.\n+ *\n+ * @return\n+ *   Non-NULL on success. Otherwise NULL is returned (the rte_errno is set).\n+ */\n+__rte_experimental\n+struct rte_memarea *rte_memarea_create(const struct rte_memarea_param *init);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice.\n+ *\n+ * Destroy memarea.\n+ *\n+ * Destroy the memarea.\n+ *\n+ * @param ma\n+ *   The pointer of memarea.\n+ *\n+ * @note The rte_errno is set if destroy failed.\n+ */\n+__rte_experimental\n+void rte_memarea_destroy(struct rte_memarea *ma);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* RTE_MEMAREA_H */\ndiff --git a/lib/memarea/version.map b/lib/memarea/version.map\nnew file mode 100644\nindex 0000000000..f36a04d7cf\n--- /dev/null\n+++ b/lib/memarea/version.map\n@@ -0,0 +1,12 @@\n+EXPERIMENTAL {\n+\tglobal:\n+\n+\trte_memarea_create;\n+\trte_memarea_destroy;\n+\n+\tlocal: *;\n+};\n+\n+INTERNAL {\n+\tlocal: *;\n+};\ndiff --git a/lib/meson.build b/lib/meson.build\nindex fac2f52cad..36821e7007 100644\n--- a/lib/meson.build\n+++ b/lib/meson.build\n@@ -42,6 +42,7 @@ libraries = [\n         'kni',\n         'latencystats',\n         'lpm',\n+        'memarea',\n         'member',\n         'pcapng',\n         'power',\n",
    "prefixes": [
        "v17",
        "1/6"
    ]
}