From patchwork Fri Jul 6 13:17:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Burakov, Anatoly" X-Patchwork-Id: 42507 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 [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 4CE041BF28; Fri, 6 Jul 2018 15:17:53 +0200 (CEST) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id D2AC51BE9C for ; Fri, 6 Jul 2018 15:17:40 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Jul 2018 06:17:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,316,1526367600"; d="scan'208";a="72741956" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga002.jf.intel.com with ESMTP; 06 Jul 2018 06:17:35 -0700 Received: from sivswdev01.ir.intel.com (sivswdev01.ir.intel.com [10.237.217.45]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id w66DHY83027497; Fri, 6 Jul 2018 14:17:34 +0100 Received: from sivswdev01.ir.intel.com (localhost [127.0.0.1]) by sivswdev01.ir.intel.com with ESMTP id w66DHYDN003818; Fri, 6 Jul 2018 14:17:34 +0100 Received: (from aburakov@localhost) by sivswdev01.ir.intel.com with LOCAL id w66DHY8j003814; Fri, 6 Jul 2018 14:17:34 +0100 From: Anatoly Burakov To: dev@dpdk.org Cc: srinath.mannam@broadcom.com, scott.branden@broadcom.com, ajit.khaparde@broadcom.com Date: Fri, 6 Jul 2018 14:17:31 +0100 Message-Id: <41225d71752906662b81fe939cd7fe47994133e1.1530881548.git.anatoly.burakov@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [RFC 10/11] malloc: allow destroying heaps X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add an API to destroy specified heap. Any memory regions still contained within the heap will be removed first. Signed-off-by: Anatoly Burakov --- lib/librte_eal/common/include/rte_malloc.h | 21 ++++++++++++++++ lib/librte_eal/common/malloc_heap.c | 29 ++++++++++++++++++++++ lib/librte_eal/common/malloc_heap.h | 3 +++ lib/librte_eal/common/rte_malloc.c | 27 ++++++++++++++++++++ lib/librte_eal/rte_eal_version.map | 1 + 5 files changed, 81 insertions(+) diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h index 25d8d3f11..239cda2ca 100644 --- a/lib/librte_eal/common/include/rte_malloc.h +++ b/lib/librte_eal/common/include/rte_malloc.h @@ -346,6 +346,27 @@ rte_malloc_heap_add_memory(const char *heap_name, void *va_addr, size_t len, int __rte_experimental rte_malloc_heap_remove_memory(const char *heap_name, void *va_addr, size_t len); +/** + * Destroys a previously created malloc heap with specified name. + * + * @note Concurrently creating or destroying heaps is not thread-safe. + * + * @note This function does not deallocate the memory backing the heap - it only + * deregisters memory from DPDK. + * + * @note This function will return a failure result if not all memory allocated + * from the heap has been freed back to malloc heap. + * + * @param heap_name + * Name of the heap to create. + * + * @return + * - 0 on successful creation. + * - -1 on error. + */ +int __rte_experimental +rte_malloc_heap_destroy(const char *heap_name); + /** * If malloc debug is enabled, check a memory block for header * and trailer markers to indicate that all is well with the block. diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c index 27dbf6e60..e447b6412 100644 --- a/lib/librte_eal/common/malloc_heap.c +++ b/lib/librte_eal/common/malloc_heap.c @@ -1039,6 +1039,35 @@ malloc_heap_create(struct malloc_heap *heap, const char *heap_name) return 0; } +int +malloc_heap_destroy(struct malloc_heap *heap) +{ + struct malloc_elem *elem; + + if (heap->alloc_count != 0) { + RTE_LOG(ERR, EAL, "Heap is still in use\n"); + rte_errno = EBUSY; + return -1; + } + elem = heap->first; + while (elem != NULL) { + struct malloc_elem *next = elem->next; + + if (destroy_seg(elem, elem->size) < 0) + return -1; + + elem = next; + } + if (heap->total_size != 0) + RTE_LOG(ERR, EAL, "Total size not zero, heap is likely corrupt\n"); + + /* we can't memset the entire thing as we're still holding the lock */ + LIST_INIT(heap->free_head); + memset(&heap->name, 0, sizeof(heap->name)); + + return 0; +} + int rte_eal_malloc_heap_init(void) { diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h index 000146365..399c9a6b1 100644 --- a/lib/librte_eal/common/malloc_heap.h +++ b/lib/librte_eal/common/malloc_heap.h @@ -38,6 +38,9 @@ malloc_heap_alloc_on_heap_id(const char *type, size_t size, int malloc_heap_create(struct malloc_heap *heap, const char *heap_name); +int +malloc_heap_destroy(struct malloc_heap *heap); + int malloc_heap_add_external_memory(struct malloc_heap *heap, void *va_addr, rte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz); diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c index 8d2eb7250..b6beee7ce 100644 --- a/lib/librte_eal/common/rte_malloc.c +++ b/lib/librte_eal/common/rte_malloc.c @@ -385,3 +385,30 @@ rte_malloc_heap_create(const char *heap_name) return malloc_heap_create(heap, heap_name); } +int +rte_malloc_heap_destroy(const char *heap_name) +{ + struct malloc_heap *heap = NULL; + int ret; + + if (heap_name == NULL || + strnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) == 0 || + strnlen(heap_name, RTE_HEAP_NAME_MAX_LEN) == + RTE_HEAP_NAME_MAX_LEN) { + rte_errno = EINVAL; + return -1; + } + /* start from non-socket heaps */ + heap = malloc_heap_find_named_heap(heap_name); + if (heap == NULL) { + RTE_LOG(ERR, EAL, "Heap %s not found\n", heap_name); + rte_errno = ENOENT; + return -1; + } + /* sanity checks done, now we can destroy the heap */ + rte_spinlock_lock(&heap->lock); + ret = malloc_heap_destroy(heap); + rte_spinlock_unlock(&heap->lock); + + return ret; +} diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 7ee79051f..cdde7eb3b 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -282,6 +282,7 @@ EXPERIMENTAL { rte_malloc_get_stats_from_heap; rte_malloc_heap_add_memory; rte_malloc_heap_create; + rte_malloc_heap_destroy; rte_malloc_heap_remove_memory; rte_mem_alloc_validator_register; rte_mem_alloc_validator_unregister;