Add an API to destroy specified heap. Any memory regions still contained within the heap will be removed first.
Signed-off-by: Anatoly Burakov <anatoly.bura...@intel.com> --- 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; -- 2.17.1