From patchwork Thu Apr 14 10:19:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olivier Matz X-Patchwork-Id: 12056 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id C40825937; Thu, 14 Apr 2016 12:20:44 +0200 (CEST) Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id D3F144A65 for ; Thu, 14 Apr 2016 12:20:24 +0200 (CEST) Received: from glumotte.dev.6wind.com (unknown [10.16.0.195]) by proxy.6wind.com (Postfix) with ESMTP id 33BAC28F40; Thu, 14 Apr 2016 12:19:41 +0200 (CEST) From: Olivier Matz To: dev@dpdk.org Cc: bruce.richardson@intel.com, stephen@networkplumber.org Date: Thu, 14 Apr 2016 12:19:42 +0200 Message-Id: <1460629199-32489-20-git-send-email-olivier.matz@6wind.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1460629199-32489-1-git-send-email-olivier.matz@6wind.com> References: <1457540381-20274-1-git-send-email-olivier.matz@6wind.com> <1460629199-32489-1-git-send-email-olivier.matz@6wind.com> Subject: [dpdk-dev] [PATCH 19/36] mempool: introduce a free callback for memory chunks X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Introduce a free callback that is passed to the populate* functions, which is used when freeing a mempool. This is unused now, but as next commits will populate the mempool with several chunks of memory, we need a way to free them properly on error. Later in the series, we will also introduce a public rte_mempool_free() and the ability for the user to populate a mempool with its own memory. For that, we also need a free callback. Signed-off-by: Olivier Matz --- lib/librte_mempool/rte_mempool.c | 27 ++++++++++++++++++++++----- lib/librte_mempool/rte_mempool.h | 8 ++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c index f2f7846..0ae899b 100644 --- a/lib/librte_mempool/rte_mempool.c +++ b/lib/librte_mempool/rte_mempool.c @@ -388,6 +388,15 @@ rte_mempool_ring_create(struct rte_mempool *mp) return 0; } +/* free a memchunk allocated with rte_memzone_reserve() */ +__rte_unused static void +rte_mempool_memchunk_mz_free(__rte_unused struct rte_mempool_memhdr *memhdr, + void *opaque) +{ + const struct rte_memzone *mz = opaque; + rte_memzone_free(mz); +} + /* Free memory chunks used by a mempool. Objects must be in pool */ static void rte_mempool_free_memchunks(struct rte_mempool *mp) @@ -405,6 +414,8 @@ rte_mempool_free_memchunks(struct rte_mempool *mp) while (!STAILQ_EMPTY(&mp->mem_list)) { memhdr = STAILQ_FIRST(&mp->mem_list); STAILQ_REMOVE_HEAD(&mp->mem_list, next); + if (memhdr->free_cb != NULL) + memhdr->free_cb(memhdr, memhdr->opaque); rte_free(memhdr); mp->nb_mem_chunks--; } @@ -415,7 +426,8 @@ rte_mempool_free_memchunks(struct rte_mempool *mp) * on error. */ static int rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr, - phys_addr_t paddr, size_t len) + phys_addr_t paddr, size_t len, rte_mempool_memchunk_free_cb_t *free_cb, + void *opaque) { unsigned total_elt_sz; unsigned i = 0; @@ -436,6 +448,8 @@ rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr, memhdr->addr = vaddr; memhdr->phys_addr = paddr; memhdr->len = len; + memhdr->free_cb = free_cb; + memhdr->opaque = opaque; if (mp->flags & MEMPOOL_F_NO_CACHE_ALIGN) off = RTE_PTR_ALIGN_CEIL(vaddr, 8) - vaddr; @@ -462,7 +476,8 @@ rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr, * number of objects added, or a negative value on error. */ static int rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr, - const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift) + const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift, + rte_mempool_memchunk_free_cb_t *free_cb, void *opaque) { uint32_t i, n; int ret, cnt = 0; @@ -480,11 +495,13 @@ rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr, ; ret = rte_mempool_populate_phys(mp, vaddr + i * pg_sz, - paddr[i], n * pg_sz); + paddr[i], n * pg_sz, free_cb, opaque); if (ret < 0) { rte_mempool_free_memchunks(mp); return ret; } + /* no need to call the free callback for next chunks */ + free_cb = NULL; cnt += ret; } return cnt; @@ -666,12 +683,12 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size, ret = rte_mempool_populate_phys(mp, obj, mp->phys_addr + ((char *)obj - (char *)mp), - objsz.total_size * n); + objsz.total_size * n, NULL, NULL); if (ret != (int)mp->size) goto exit_unlock; } else { ret = rte_mempool_populate_phys_tab(mp, vaddr, - paddr, pg_num, pg_shift); + paddr, pg_num, pg_shift, NULL, NULL); if (ret != (int)mp->size) goto exit_unlock; } diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h index 0e4641e..e06ccfc 100644 --- a/lib/librte_mempool/rte_mempool.h +++ b/lib/librte_mempool/rte_mempool.h @@ -187,6 +187,12 @@ struct rte_mempool_objtlr { STAILQ_HEAD(rte_mempool_memhdr_list, rte_mempool_memhdr); /** + * Callback used to free a memory chunk + */ +typedef void (rte_mempool_memchunk_free_cb_t)(struct rte_mempool_memhdr *memhdr, + void *opaque); + +/** * Mempool objects memory header structure * * The memory chunks where objects are stored. Each chunk is virtually @@ -198,6 +204,8 @@ struct rte_mempool_memhdr { void *addr; /**< Virtual address of the chunk */ phys_addr_t phys_addr; /**< Physical address of the chunk */ size_t len; /**< length of the chunk */ + rte_mempool_memchunk_free_cb_t *free_cb; /**< Free callback */ + void *opaque; /**< Argument passed to the free callback */ }; /**