From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 24AF9C376 for ; Sat, 6 Jun 2015 12:32:16 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 06 Jun 2015 03:32:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,563,1427785200"; d="scan'208";a="738233870" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga002.fm.intel.com with ESMTP; 06 Jun 2015 03:32:14 -0700 Received: from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com [10.237.217.46]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t56AWDeC024227; Sat, 6 Jun 2015 11:32:13 +0100 Received: from sivswdev02.ir.intel.com (localhost [127.0.0.1]) by sivswdev02.ir.intel.com with ESMTP id t56AWDmL028300; Sat, 6 Jun 2015 11:32:13 +0100 Received: (from smonroy@localhost) by sivswdev02.ir.intel.com with id t56AWDcY028296; Sat, 6 Jun 2015 11:32:13 +0100 From: Sergio Gonzalez Monroy To: dev@dpdk.org Date: Sat, 6 Jun 2015 11:32:11 +0100 Message-Id: <1433586732-28217-7-git-send-email-sergio.gonzalez.monroy@intel.com> X-Mailer: git-send-email 1.8.5.4 In-Reply-To: <1433586732-28217-1-git-send-email-sergio.gonzalez.monroy@intel.com> References: <1431103079-18096-1-git-send-email-sergio.gonzalez.monroy@intel.com> <1433586732-28217-1-git-send-email-sergio.gonzalez.monroy@intel.com> Subject: [dpdk-dev] [PATCH v2 6/7] eal: new rte_memzone_free 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: , X-List-Received-Date: Sat, 06 Jun 2015 10:32:17 -0000 Implement rte_memzone_free which, as its name implies, would free a memzone. Currently memzone are tracked in an array and cannot be free. To be able to reuse the same array to track memzones, we have to change how we keep track of reserved memzones. With this patch, any memzone with addr NULL is not used, so we also need to change how we look for the next memzone entry free. Signed-off-by: Sergio Gonzalez Monroy --- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 6 +++ lib/librte_eal/common/eal_common_memzone.c | 50 +++++++++++++++++++++-- lib/librte_eal/common/include/rte_eal_memconfig.h | 2 +- lib/librte_eal/common/include/rte_memzone.h | 11 +++++ lib/librte_eal/linuxapp/eal/eal_ivshmem.c | 28 +++++++++++-- lib/librte_eal/linuxapp/eal/rte_eal_version.map | 6 +++ 6 files changed, 95 insertions(+), 8 deletions(-) diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map index 0401be2..7110816 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map @@ -105,3 +105,9 @@ DPDK_2.0 { local: *; }; + +DPDK_2.1 { + global: + + rte_memzone_free; +} DPDK_2.0; diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c index 742f6c9..0b458ec 100644 --- a/lib/librte_eal/common/eal_common_memzone.c +++ b/lib/librte_eal/common/eal_common_memzone.c @@ -76,6 +76,23 @@ memzone_lookup_thread_unsafe(const char *name) return NULL; } +static inline struct rte_memzone * +get_next_free_memzone(void) +{ + struct rte_mem_config *mcfg; + unsigned i = 0; + + /* get pointer to global configuration */ + mcfg = rte_eal_get_configuration()->mem_config; + + for (i = 0; i < RTE_MAX_MEMZONE && mcfg->memzone[i].addr != NULL; i++); + + if (i < RTE_MAX_MEMZONE) + return &mcfg->memzone[i]; + + return NULL; +} + /* * Return a pointer to a correctly filled memzone descriptor. If the * allocation cannot be done, return NULL. @@ -140,7 +157,7 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len, mcfg = rte_eal_get_configuration()->mem_config; /* no more room in config */ - if (mcfg->memzone_idx >= RTE_MAX_MEMZONE) { + if (mcfg->memzone_cnt >= RTE_MAX_MEMZONE) { RTE_LOG(ERR, EAL, "%s(): No more room in config\n", __func__); rte_errno = ENOSPC; return NULL; @@ -214,7 +231,8 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len, const struct malloc_elem *elem = malloc_elem_from_data(mz_addr); /* fill the zone in config */ - struct rte_memzone *mz = &mcfg->memzone[mcfg->memzone_idx++]; + struct rte_memzone *mz = get_next_free_memzone(); + mcfg->memzone_cnt++; snprintf(mz->name, sizeof(mz->name), "%s", name); mz->phys_addr = rte_malloc_virt2phy(mz_addr); mz->addr = mz_addr; @@ -290,6 +308,32 @@ rte_memzone_reserve_bounded(const char *name, size_t len, return mz; } +int +rte_memzone_free(const struct rte_memzone *mz) +{ + struct rte_mem_config *mcfg; + int ret = 0; + void *addr; + unsigned idx; + + if (mz == NULL) + return -EINVAL; + + mcfg = rte_eal_get_configuration()->mem_config; + + rte_rwlock_read_lock(&mcfg->mlock); + + idx = ((uintptr_t)mz - (uintptr_t)mcfg->memzone); + idx = idx / sizeof(struct rte_memzone); + + addr = mcfg->memzone[idx].addr; + mcfg->memzone[idx].addr = NULL; + rte_free(addr); + + rte_rwlock_read_unlock(&mcfg->mlock); + + return ret; +} /* * Lookup for the memzone identified by the given name @@ -363,7 +407,7 @@ rte_eal_memzone_init(void) rte_rwlock_write_lock(&mcfg->mlock); /* delete all zones */ - mcfg->memzone_idx = 0; + mcfg->memzone_cnt = 0; memset(mcfg->memzone, 0, sizeof(mcfg->memzone)); rte_rwlock_write_unlock(&mcfg->mlock); diff --git a/lib/librte_eal/common/include/rte_eal_memconfig.h b/lib/librte_eal/common/include/rte_eal_memconfig.h index 055212a..2015074 100644 --- a/lib/librte_eal/common/include/rte_eal_memconfig.h +++ b/lib/librte_eal/common/include/rte_eal_memconfig.h @@ -67,7 +67,7 @@ struct rte_mem_config { rte_rwlock_t qlock; /**< used for tailq operation for thread safe. */ rte_rwlock_t mplock; /**< only used by mempool LIB for thread-safe. */ - uint32_t memzone_idx; /**< Index of memzone */ + uint32_t memzone_cnt; /**< Number of allocated memzones */ /* memory segments and zones */ struct rte_memseg memseg[RTE_MAX_MEMSEG]; /**< Physmem descriptors. */ diff --git a/lib/librte_eal/common/include/rte_memzone.h b/lib/librte_eal/common/include/rte_memzone.h index 81b6ad4..3f54bde 100644 --- a/lib/librte_eal/common/include/rte_memzone.h +++ b/lib/librte_eal/common/include/rte_memzone.h @@ -240,6 +240,17 @@ const struct rte_memzone *rte_memzone_reserve_bounded(const char *name, unsigned flags, unsigned align, unsigned bound); /** + * Free a memzone. + * + * @param mz + * A pointer to the memzone + * @return + * -EINVAL - invalid parameter + * 0 - sucess + */ +int rte_memzone_free(const struct rte_memzone *mz); + +/** * Lookup for a memzone. * * Get a pointer to a descriptor of an already reserved memory diff --git a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c index facfb80..db021c7 100644 --- a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c +++ b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c @@ -735,6 +735,23 @@ map_all_segments(void) return 0; } +static inline struct rte_memzone * +get_next_free_memzone(void) +{ + struct rte_mem_config *mcfg; + unsigned i = 0; + + /* get pointer to global configuration */ + mcfg = rte_eal_get_configuration()->mem_config; + + for (i = 0; i < RTE_MAX_MEMZONE && mcfg->memzone[i].addr != NULL; i++); + + if (i < RTE_MAX_MEMZONE) + return &mcfg->memzone[i]; + + return NULL; +} + /* this happens at a later stage, after general EAL memory initialization */ int rte_eal_ivshmem_obj_init(void) @@ -768,12 +785,12 @@ rte_eal_ivshmem_obj_init(void) seg = &ivshmem_config->segment[i]; /* add memzone */ - if (mcfg->memzone_idx == RTE_MAX_MEMZONE) { + if (mcfg->memzone_cnt == RTE_MAX_MEMZONE) { RTE_LOG(ERR, EAL, "No more memory zones available!\n"); return -1; } - idx = mcfg->memzone_idx; + idx = get_next_free_memzone(); RTE_LOG(DEBUG, EAL, "Found memzone: '%s' at %p (len 0x%" PRIx64 ")\n", seg->entry.mz.name, seg->entry.mz.addr, seg->entry.mz.len); @@ -796,15 +813,18 @@ rte_eal_ivshmem_obj_init(void) } } - mcfg->memzone_idx++; + mcfg->memzone_cnt++; } rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); /* find rings */ - for (i = 0; i < mcfg->memzone_idx; i++) { + for (i = 0; i < RTE_MAX_MEMZONE; i++) { mz = &mcfg->memzone[i]; + if (mz->addr == NULL) + continue; + /* check if memzone has a ring prefix */ if (strncmp(mz->name, RTE_RING_MZ_PREFIX, sizeof(RTE_RING_MZ_PREFIX) - 1) != 0) diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index c107b05..e537b42 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -111,3 +111,9 @@ DPDK_2.0 { local: *; }; + +DPDK_2.1 { + global: + + rte_memzone_free; +} DPDK_2.0; -- 1.9.3