From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 924F5A0544; Tue, 11 Oct 2022 01:33:34 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 3895D40DFD; Tue, 11 Oct 2022 01:33:34 +0200 (CEST) Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by mails.dpdk.org (Postfix) with ESMTP id D4EA740146 for ; Tue, 11 Oct 2022 01:33:31 +0200 (CEST) Received: from dggpeml500024.china.huawei.com (unknown [172.30.72.56]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4MmZs84jVJzpVVn; Tue, 11 Oct 2022 07:30:20 +0800 (CST) Received: from [10.82.131.128] (10.82.131.128) by dggpeml500024.china.huawei.com (7.185.36.10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Tue, 11 Oct 2022 07:33:29 +0800 Message-ID: <1faa55d7-6fab-9d1c-4416-30cf16c3fd20@huawei.com> Date: Tue, 11 Oct 2022 07:33:39 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.2.1 Subject: Re: [PATCH v5 01/10] memarea: introduce memarea library To: =?UTF-8?Q?Mattias_R=c3=b6nnblom?= , datshan , , , , , CC: , References: <20220721044648.6817-1-fengchengwen@huawei.com> <20221005040952.8166-1-datshan@qq.com> <7ea65099-1b7b-8e43-a956-0969ee7425ee@lysator.liu.se> <7bbdaac0-00c0-bf19-47a5-da8c01a1f2a8@huawei.com> Content-Language: en-US From: fengchengwen In-Reply-To: Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit X-Originating-IP: [10.82.131.128] X-ClientProxiedBy: dggpeml100007.china.huawei.com (7.185.36.28) To dggpeml500024.china.huawei.com (7.185.36.10) X-CFilter-Loop: Reflected X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org On 2022/10/11 0:53, Mattias Rönnblom wrote: > On 2022-10-08 09:53, fengchengwen wrote: >> Hi Mattias, Thanks for your review, most will fix in v6. >> >> On 2022/10/7 4:15, Mattias Rönnblom wrote: >>> On 2022-10-05 06:09, datshan wrote: >>>> From: Chengwen Feng >>>> >>>> The memarea library is an allocator of variable-size object which >>>> based >>>> on a memory region. >>>> >>>> This patch provides create/destroy API. >>>> >>>> Signed-off-by: Chengwen Feng >>>> --- >>>>    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  |  39 ++++++ >>>>    doc/guides/rel_notes/release_22_11.rst |   6 + >>>>    lib/eal/common/eal_common_log.c        |   1 + >>>>    lib/eal/include/rte_log.h              |   1 + >>>>    lib/memarea/memarea_private.h          |  30 +++++ >>>>    lib/memarea/meson.build                |  16 +++ >>>>    lib/memarea/rte_memarea.c              | 157 >>>> +++++++++++++++++++++++++ >>>>    lib/memarea/rte_memarea.h              | 145 >>>> +++++++++++++++++++++++ >>>>    lib/memarea/version.map                |  12 ++ >>>>    lib/meson.build                        |   1 + >>>>    14 files changed, 417 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 >>>> >>>> diff --git a/MAINTAINERS b/MAINTAINERS >>>> index a55b379d73..b9c638221d 100644 >>>> --- a/MAINTAINERS >>>> +++ b/MAINTAINERS >>>> @@ -1550,6 +1550,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 >>>> +F: lib/memarea >>>> +F: doc/guides/prog_guide/memarea_lib.rst >>>> + >>>>    Membership - EXPERIMENTAL >>>>    M: Yipeng Wang >>>>    M: Sameh Gobriel >>>> diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md >>>> index de488c7abf..24456604f8 100644 >>>> --- a/doc/api/doxy-api-index.md >>>> +++ b/doc/api/doxy-api-index.md >>>> @@ -62,7 +62,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 f0886c3bd1..8334ebcbd6 100644 >>>> --- a/doc/api/doxy-api.conf.in >>>> +++ b/doc/api/doxy-api.conf.in >>>> @@ -53,6 +53,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..b96dad15f6 >>>> --- /dev/null >>>> +++ b/doc/guides/prog_guide/memarea_lib.rst >>>> @@ -0,0 +1,39 @@ >>>> +..  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: >>>> + >>>> +* The default aligement size is ``RTE_CACHE_LINE_SIZE``. >>>> + >>>> +* The memory region can be initialized from the following memory >>>> sources: >>>> +  a) RTE memory: e.g. invoke ``rte_malloc_socket`` to obtain. b) >>>> System API: >>>> +  e.g. invoke posix_memalign to obtain. c) User provided address: >>>> it can be from >>>> +  extendedd memory as long as it is available. d) User provided >>>> memarea: it can >>>> +  be from another memarea. >>>> + >>>> +* It provides refcnt feature which could be useful in multi-reader >>>> scenario. >>>> + >>>> +* 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, >>>> 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. >>>> + >>>> +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 5d8ef669b8..4c1f760b98 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. >>>> + >>>>    * **Added configuration for asynchronous flow connection >>>> tracking.** >>>>        Added connection tracking action number hint to >>>> ``rte_flow_configure`` >>>> diff --git a/lib/eal/common/eal_common_log.c >>>> b/lib/eal/common/eal_common_log.c >>>> index bd7b188ceb..3d62af59c6 100644 >>>> --- a/lib/eal/common/eal_common_log.c >>>> +++ b/lib/eal/common/eal_common_log.c >>>> @@ -369,6 +369,7 @@ static const struct logtype logtype_strings[] = { >>>>        {RTE_LOGTYPE_EFD,        "lib.efd"}, >>>>        {RTE_LOGTYPE_EVENTDEV,   "lib.eventdev"}, >>>>        {RTE_LOGTYPE_GSO,        "lib.gso"}, >>>> +    {RTE_LOGTYPE_MEMAREA,    "lib.memarea"}, >>>>        {RTE_LOGTYPE_USER1,      "user1"}, >>>>        {RTE_LOGTYPE_USER2,      "user2"}, >>>>        {RTE_LOGTYPE_USER3,      "user3"}, >>>> 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..c76392d3e6 >>>> --- /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 >>>> + >>>> +#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; >>>> + >>> >>> Why is the elem type cache line aligned? Need the elem data start be >>> cache line aligned? >> >> Yes, the elem data align at cache-line default. >> >>> >>>> +TAILQ_HEAD(memarea_elem_list, memarea_elem); >>>> + >>>> +struct rte_memarea { >>>> +    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..868da7661d >>>> --- /dev/null >>>> +++ b/lib/memarea/rte_memarea.c >>>> @@ -0,0 +1,157 @@ >>>> +/* SPDX-License-Identifier: BSD-3-Clause >>>> + * Copyright(c) 2022 HiSilicon Limited >>>> + */ >>>> + >>>> +#include >>>> +#include >>>> + >>>> +#include >>>> +#include >>>> +#include >>>> +#include >>>> + >>>> +#include "rte_memarea.h" >>>> +#include "memarea_private.h" >>>> + >>>> +static int >>>> +memarea_check_param(const struct rte_memarea_param *init) >>>> +{ >>>> +    size_t len; >>>> + >>>> +    if (init == NULL) { >>>> +        RTE_LOG(ERR, MEMAREA, "memarea init param is NULL!\n"); >>>> +        return -EINVAL; >>>> +    } >>>> + >>>> +    len = strnlen(init->name, RTE_MEMAREA_NAMESIZE); >>>> +    if (len == 0 || len >= RTE_MEMAREA_NAMESIZE) { >>>> +        RTE_LOG(ERR, MEMAREA, "memarea name size %zu invalid!\n", >>>> len); >>>> +        return -EINVAL; >>>> +    } >>>> + >>>> +    if (init->source != RTE_MEMAREA_SOURCE_RTE_MEMORY && >>>> +        init->source != RTE_MEMAREA_SOURCE_SYSTEM_API && >>>> +        init->source != RTE_MEMAREA_SOURCE_USER_ADDR && >>>> +        init->source != RTE_MEMAREA_SOURCE_USER_MEMAREA) { >>>> +        RTE_LOG(ERR, MEMAREA, "memarea: %s source: %d not >>>> supported!\n", >>>> +            init->name, init->source); >>>> +        return -EINVAL; >>>> +    } >>>> + >>>> +    if (init->total_sz <= sizeof(struct memarea_elem)) { >>>> +        RTE_LOG(ERR, MEMAREA, "memarea: %s total-size: %zu too >>>> small!\n", >>>> +            init->name, init->total_sz); >>>> +        return -EINVAL; >>>> +    } >>>> + >>>> +    if (init->source == RTE_MEMAREA_SOURCE_USER_ADDR && >>>> init->user_addr == NULL) { >>>> +        RTE_LOG(ERR, MEMAREA, "memarea: %s user provided addr is >>>> NULL!\n", init->name); >>>> +        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: %s user provided addr >>>> should align: %d!\n", >>>> +            init->name, RTE_CACHE_LINE_SIZE); >>>> +        return -EINVAL; >>>> +    } >>>> + >>>> +    if (init->source == RTE_MEMAREA_SOURCE_USER_MEMAREA && >>>> init->user_memarea == NULL) { >>>> +        RTE_LOG(ERR, MEMAREA, "memarea: %s user provided memarea >>>> is NULL!\n", init->name); >>>> +        return -EINVAL; >>>> +    } >>>> + >>>> +    if (init->alg != RTE_MEMAREA_ALG_DEFAULT) { >>>> +        RTE_LOG(ERR, MEMAREA, "memarea: %s alg: %d not supported!\n", >>>> +            init->name, init->alg); >>>> +        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_RTE_MEMORY) >>> >>> Delete MEMORY. Of course it's memory. What else? If you want to make >>> it clear it's from the RTE heap, it should spell out HEAP. Or MALLOC. >> >> HEAP seem better. >> >>> >>>> +        ptr = rte_malloc_socket(NULL, init->total_sz, >>>> RTE_CACHE_LINE_SIZE, >>>> +                    init->numa_socket); >>>> +    else if (init->source == RTE_MEMAREA_SOURCE_SYSTEM_API) >>>> +        ptr = memarea_alloc_from_system_api(init->total_sz); >>> >>> "SYSTEM_API" doesn't strike me as a good name. >>> >>> RTE_MEMAREA_SOURCE_LIBC >> >> LIBC seem better. >> >>> RTE_MEMAREA_SOURCE_STD_HEAP >>> or at least remove API so it'll be >>> RTE_MEMAREA_SOURCE_SYSTEM >>> >>>> +    else if (init->source == RTE_MEMAREA_SOURCE_USER_ADDR) >>> >>> I would delete "ADDR". >> >> +1 >> >>> >>>> +        ptr = init->user_addr; >>>> + >>>> +    if (ptr == NULL) >>>> +        RTE_LOG(ERR, MEMAREA, "memarea: %s alloc memory area >>>> fail!\n", init->name); >>>> + >>>> +    return ptr; >>>> +} >>>> + >>>> +struct rte_memarea * >>>> +rte_memarea_create(const struct rte_memarea_param *init) >>>> +{ >>>> +    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); >>>> +    if (ma == NULL) { >>>> +        RTE_LOG(ERR, MEMAREA, "malloc memarea: %s management obj >>>> fail!\n", init->name); >>>> +        return NULL; >>>> +    } >>>> + >>>> +    ma->init = *init; >>>> +    rte_spinlock_init(&ma->lock); >>>> +    TAILQ_INIT(&ma->elem_list); >>>> +    TAILQ_INIT(&ma->free_list); >>>> +    ma->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(&ma->elem_list, elem, elem_node); >>>> +    TAILQ_INSERT_TAIL(&ma->free_list, elem, free_node); >>>> + >>>> +    return ma; >>>> +} >>>> + >>>> +static void >>>> +memarea_free_area(struct rte_memarea *ma) >>>> +{ >>>> +    if (ma->init.source == RTE_MEMAREA_SOURCE_RTE_MEMORY) >>>> +        rte_free(ma->area_addr); >>>> +    else if (ma->init.source == RTE_MEMAREA_SOURCE_SYSTEM_API) >>>> +        free(ma->area_addr); >>>> +} >>>> + >>>> +void >>>> +rte_memarea_destroy(struct rte_memarea *ma) >>>> +{ >>>> +    if (ma == NULL) >>>> +        return; >>>> +    memarea_free_area(ma); >>>> +    rte_free(ma); >>>> +} >>>> diff --git a/lib/memarea/rte_memarea.h b/lib/memarea/rte_memarea.h >>>> new file mode 100644 >>>> index 0000000000..543cda4cac >>>> --- /dev/null >>>> +++ b/lib/memarea/rte_memarea.h >>>> @@ -0,0 +1,145 @@ >>>> +/* SPDX-License-Identifier: BSD-3-Clause >>>> + * Copyright(c) 2022 HiSilicon Limited >>>> + */ >>>> + >>>> +#ifndef RTE_MEMAREA_H >>>> +#define RTE_MEMAREA_H >>>> + >>>> +/** >>>> + * @file >>>> + * RTE Memarea. >>>> + * >>>> + * The memarea is an allocator of variable-size object which based >>>> on a memory >>>> + * region. It has the following features: >>>> + * >>>> + * - The default alignment size is RTE_CACHE_LINE_SIZE. >>> >>> This can be read as two things: the object size is aligned, or the >>> start address is aligned. >> >> It means the start address align, will define more clear in v6. >> >>> >>>> + * - The memory region can be initialized from the following >>>> memory sources: >>>> + *   1. RTE memory: e.g. invoke rte_malloc_socket to obtain. >>> >>> Remove "to obtain", or add "memory" after "obtain". Do you really >>> mean "e.g.", and not "i.e."? >> >> will fix in v6. >> >>> >>>> + *   2. System API: e.g. invoke posix_memalign to obtain. >>>> + *   3. User provided address: it can be from extended memory as >>>> long as it is >>>> + *      available. The address must be aligned to >>>> RTE_CACHE_LINE_SIZE. >>> >>> What is extended memory? >> >> Like rte_extmen >> >>> >>>> + *   4) 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 |   | object | >>>> + *            -------------   -------------   ---------- >>>> + *         \endcode >>>> + *      As shown above, the memarea-2/3 both create from >>>> memarea-1's memory. >>>> + * - It provides refcnt feature which could be useful in >>>> multi-reader scenario. >>>> + * - 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. >>>> + */ >>>> + >>>> +#include >>>> +#include >>>> +#include >>>> + >>>> +#include >>>> + >>>> +#ifdef __cplusplus >>>> +extern "C" { >>>> +#endif >>>> + >>>> +#define RTE_MEMAREA_NAMESIZE    64 >>>> + >>>> +/** >>>> + * Memarea memory source. >>>> + */ >>>> +enum rte_memarea_source { >>>> +    /** Memory source comes from rte memory. */ >>>> +    RTE_MEMAREA_SOURCE_RTE_MEMORY, >>>> +    /** Memory source comes from system API. */ >>>> +    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, >>>> +}; >>>> + >>>> +/** >>>> + * Memarea memory management algorithm. >>>> + */ >>>> +enum rte_memarea_alg { >>>> +    /* The default management algorithm is a variant of the next fit >>>> +     * algorithm. It uses a free-list to apply for memory and uses an >>>> +     * element-list in ascending order of address to support merging >>>> +     * upon free. >>>> +     */ >>>> +    RTE_MEMAREA_ALG_DEFAULT, >>>> +}; > > Do you need to expose the algorithm/management scheme option in the > public API, if there is only one implementation to choose from? Yes, we plan to support SLAB algorithm in future by adding a new alg. > > You can always have a rte_memarea_create_alg(/../) in the future, or > just change the signature between ABI-breaking releases. I don't think add a new API is a good idea. You can see that, we put all init parameter in one struct in this design, and could extend function by adding new field . > > > Also, shouldn't the default algorithm have name? Rather than just > DEFAULT. RTE_MEMAREA_ALG_NEXTFIT maybe. Yes, will fix in next version. > >>>> + >>>> +struct rte_memarea; >>>> + >>>> +struct rte_memarea_param { >>> >>> Does this struct need to be public? >> >> Yes, the rte_memarea_param contains create parameters for create >> memarea which need be public. >> > > Why isn't the public API just a bunch of create-function parameters? > Or, alternatively, you have an assortment of create functions, for > different combinations of parameters. Then you don't have to think > about having reserved bits or other kind of ABI-related issues due to > the struct being public. These are two API design styles,and I prefer the one create-function API style just it seem simple (by inner usage voice). > >> And rte_memarea which pointer implementation struction which just a >> declare here. >> >>> >>>> +    char name[RTE_MEMAREA_NAMESIZE]; /**< Name of memarea. */ >>>> +    enum rte_memarea_source source;  /**< Memory source of >>>> memarea. */ >>>> +    enum rte_memarea_alg alg;        /**< Memory management >>>> algorithm. */ >>>> +    size_t total_sz;                 /**< total size (bytes) of >>>> memarea. */ >>>> +    /** Indicates whether the memarea API should be MT-safe. */ >>>> +    uint32_t mt_safe : 1; >>> >>> Why not bool? >> >> Use bit field other than bool will provides more reserved field. >> >>> >>>> +    union { >>>> +        /** Numa socket from which to apply for memarea's memory, >>>> this >>>> +         * field is valid only when the source is set to be >>>> +         * RTE_MEMAREA_SOURCE_RTE_MEMORY. >>>> +         */ >>>> +        int numa_socket; >>>> +        /** 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', >>> >>> . >