X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Frte_malloc.c;h=9d39e58c08ed7a079078df55a027b47dcd542c68;hb=2a5d547a4a9b7b4644e0b75d90d3b577a34e6d11;hp=5f07b981ad97e975b08fb407a261de6c96b6ec73;hpb=b3e735e16e07de79fb09dfb485eae2965c952d74;p=dpdk.git diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c index 5f07b981ad..9d39e58c08 100644 --- a/lib/librte_eal/common/rte_malloc.c +++ b/lib/librte_eal/common/rte_malloc.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2010-2014 Intel Corporation + * Copyright(c) 2010-2019 Intel Corporation */ #include @@ -21,27 +21,46 @@ #include #include +#include + #include #include "malloc_elem.h" #include "malloc_heap.h" #include "eal_memalloc.h" +#include "eal_memcfg.h" +#include "eal_private.h" /* Free the memory space back to heap */ -void rte_free(void *addr) +static void +mem_free(void *addr, const bool trace_ena) { + if (trace_ena) + rte_eal_trace_mem_free(addr); + if (addr == NULL) return; if (malloc_heap_free(malloc_elem_from_data(addr)) < 0) RTE_LOG(ERR, EAL, "Error: Invalid memory\n"); } -/* - * Allocate memory on specified heap. - */ -void * -rte_malloc_socket(const char *type, size_t size, unsigned int align, - int socket_arg) +void +rte_free(void *addr) { + return mem_free(addr, true); +} + +void +eal_free_no_trace(void *addr) +{ + return mem_free(addr, false); +} + +static void * +malloc_socket(const char *type, size_t size, unsigned int align, + int socket_arg, const bool trace_ena) +{ + void *ptr; + /* return NULL if size is 0 or alignment is not power-of-2 */ if (size == 0 || (align && !rte_is_power_of_2(align))) return NULL; @@ -55,8 +74,28 @@ rte_malloc_socket(const char *type, size_t size, unsigned int align, !rte_eal_has_hugepages()) socket_arg = SOCKET_ID_ANY; - return malloc_heap_alloc(type, size, socket_arg, 0, + ptr = malloc_heap_alloc(type, size, socket_arg, 0, align == 0 ? 1 : align, 0, false); + + if (trace_ena) + rte_eal_trace_mem_malloc(type, size, align, socket_arg, ptr); + return ptr; +} + +/* + * Allocate memory on specified heap. + */ +void * +rte_malloc_socket(const char *type, size_t size, unsigned int align, + int socket_arg) +{ + return malloc_socket(type, size, align, socket_arg, true); +} + +void * +eal_malloc_no_trace(const char *type, size_t size, unsigned int align) +{ + return malloc_socket(type, size, align, SOCKET_ID_ANY, false); } /* @@ -74,7 +113,20 @@ rte_malloc(const char *type, size_t size, unsigned align) void * rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket) { - return rte_malloc_socket(type, size, align, socket); + void *ptr = rte_malloc_socket(type, size, align, socket); + +#ifdef RTE_MALLOC_DEBUG + /* + * If DEBUG is enabled, then freed memory is marked with poison + * value and set to zero on allocation. + * If DEBUG is not enabled then memory is already zeroed. + */ + if (ptr != NULL) + memset(ptr, 0, size); +#endif + + rte_eal_trace_mem_zmalloc(type, size, align, socket, ptr); + return ptr; } /* @@ -105,13 +157,13 @@ rte_calloc(const char *type, size_t num, size_t size, unsigned align) } /* - * Resize allocated memory. + * Resize allocated memory on specified heap. */ void * -rte_realloc(void *ptr, size_t size, unsigned align) +rte_realloc_socket(void *ptr, size_t size, unsigned int align, int socket) { if (ptr == NULL) - return rte_malloc(NULL, size, align); + return rte_malloc_socket(NULL, size, align, socket); struct malloc_elem *elem = malloc_elem_from_data(ptr); if (elem == NULL) { @@ -120,23 +172,43 @@ rte_realloc(void *ptr, size_t size, unsigned align) } size = RTE_CACHE_LINE_ROUNDUP(size), align = RTE_CACHE_LINE_ROUNDUP(align); - /* check alignment matches first, and if ok, see if we can resize block */ - if (RTE_PTR_ALIGN(ptr,align) == ptr && - malloc_heap_resize(elem, size) == 0) + + /* check requested socket id and alignment matches first, and if ok, + * see if we can resize block + */ + if ((socket == SOCKET_ID_ANY || + (unsigned int)socket == elem->heap->socket_id) && + RTE_PTR_ALIGN(ptr, align) == ptr && + malloc_heap_resize(elem, size) == 0) { + rte_eal_trace_mem_realloc(size, align, socket, ptr); return ptr; + } - /* either alignment is off, or we have no room to expand, - * so move data. */ - void *new_ptr = rte_malloc(NULL, size, align); + /* either requested socket id doesn't match, alignment is off + * or we have no room to expand, + * so move the data. + */ + void *new_ptr = rte_malloc_socket(NULL, size, align, socket); if (new_ptr == NULL) return NULL; - const unsigned old_size = elem->size - MALLOC_ELEM_OVERHEAD; + /* elem: |pad|data_elem|data|trailer| */ + const size_t old_size = elem->size - elem->pad - MALLOC_ELEM_OVERHEAD; rte_memcpy(new_ptr, ptr, old_size < size ? old_size : size); rte_free(ptr); + rte_eal_trace_mem_realloc(size, align, socket, new_ptr); return new_ptr; } +/* + * Resize allocated memory. + */ +void * +rte_realloc(void *ptr, size_t size, unsigned int align) +{ + return rte_realloc_socket(ptr, size, align, SOCKET_ID_ANY); +} + int rte_malloc_validate(const void *ptr, size_t *size) { @@ -156,39 +228,29 @@ rte_malloc_get_socket_stats(int socket, struct rte_malloc_socket_stats *socket_stats) { struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; - int heap_idx, ret = -1; - - rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); + int heap_idx; heap_idx = malloc_socket_to_heap_id(socket); if (heap_idx < 0) - goto unlock; + return -1; - ret = malloc_heap_get_stats(&mcfg->malloc_heaps[heap_idx], + return malloc_heap_get_stats(&mcfg->malloc_heaps[heap_idx], socket_stats); -unlock: - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); - - return ret; } /* * Function to dump contents of all heaps */ -void __rte_experimental +void rte_malloc_dump_heaps(FILE *f) { struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; unsigned int idx; - rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); - for (idx = 0; idx < RTE_MAX_HEAPS; idx++) { fprintf(f, "Heap id: %u\n", idx); malloc_heap_dump(&mcfg->malloc_heaps[idx], f); } - - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); } int @@ -206,7 +268,7 @@ rte_malloc_heap_get_socket(const char *name) rte_errno = EINVAL; return -1; } - rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_lock(); for (idx = 0; idx < RTE_MAX_HEAPS; idx++) { struct malloc_heap *tmp = &mcfg->malloc_heaps[idx]; @@ -222,7 +284,7 @@ rte_malloc_heap_get_socket(const char *name) rte_errno = ENOENT; ret = -1; } - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_unlock(); return ret; } @@ -237,7 +299,7 @@ rte_malloc_heap_socket_is_external(int socket_id) if (socket_id == SOCKET_ID_ANY) return 0; - rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_lock(); for (idx = 0; idx < RTE_MAX_HEAPS; idx++) { struct malloc_heap *tmp = &mcfg->malloc_heaps[idx]; @@ -247,7 +309,7 @@ rte_malloc_heap_socket_is_external(int socket_id) break; } } - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_unlock(); return ret; } @@ -262,8 +324,6 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type) unsigned int heap_id; struct rte_malloc_socket_stats sock_stats; - rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); - /* Iterate through all initialised heaps */ for (heap_id = 0; heap_id < RTE_MAX_HEAPS; heap_id++) { struct malloc_heap *heap = &mcfg->malloc_heaps[heap_id]; @@ -280,7 +340,6 @@ rte_malloc_dump_stats(FILE *f, __rte_unused const char *type) fprintf(f, "\tAlloc_count:%u,\n",sock_stats.alloc_count); fprintf(f, "\tFree_count:%u,\n", sock_stats.free_count); } - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); return; } @@ -338,20 +397,23 @@ int rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len, rte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz) { - struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; struct malloc_heap *heap = NULL; + struct rte_memseg_list *msl; unsigned int n; int ret; if (heap_name == NULL || va_addr == NULL || page_sz == 0 || !rte_is_power_of_2(page_sz) || + RTE_ALIGN(len, page_sz) != len || + !rte_is_aligned(va_addr, page_sz) || + ((len / page_sz) != n_pages && iova_addrs != 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; } - rte_rwlock_write_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_lock(); /* find our heap */ heap = find_named_heap(heap_name); @@ -367,19 +429,21 @@ rte_malloc_heap_memory_add(const char *heap_name, void *va_addr, size_t len, goto unlock; } n = len / page_sz; - if (n != n_pages && iova_addrs != NULL) { - rte_errno = EINVAL; + + msl = malloc_heap_create_external_seg(va_addr, iova_addrs, n, page_sz, + heap_name, heap->socket_id); + if (msl == NULL) { ret = -1; goto unlock; } rte_spinlock_lock(&heap->lock); - ret = malloc_heap_add_external_memory(heap, va_addr, iova_addrs, n, - page_sz); + ret = malloc_heap_add_external_memory(heap, msl); + msl->heap = 1; /* mark it as heap segment */ rte_spinlock_unlock(&heap->lock); unlock: - rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_unlock(); return ret; } @@ -387,8 +451,8 @@ unlock: int rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len) { - struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; struct malloc_heap *heap = NULL; + struct rte_memseg_list *msl; int ret; if (heap_name == NULL || va_addr == NULL || len == 0 || @@ -398,7 +462,7 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len) rte_errno = EINVAL; return -1; } - rte_rwlock_write_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_lock(); /* find our heap */ heap = find_named_heap(heap_name); if (heap == NULL) { @@ -413,73 +477,31 @@ rte_malloc_heap_memory_remove(const char *heap_name, void *va_addr, size_t len) goto unlock; } + msl = malloc_heap_find_external_seg(va_addr, len); + if (msl == NULL) { + ret = -1; + goto unlock; + } + rte_spinlock_lock(&heap->lock); ret = malloc_heap_remove_external_memory(heap, va_addr, len); rte_spinlock_unlock(&heap->lock); + if (ret != 0) + goto unlock; + + ret = malloc_heap_destroy_external_seg(msl); unlock: - rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_unlock(); return ret; } -struct sync_mem_walk_arg { - void *va_addr; - size_t len; - int result; - bool attach; -}; - -static int -sync_mem_walk(const struct rte_memseg_list *msl, void *arg) -{ - struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; - struct sync_mem_walk_arg *wa = arg; - size_t len = msl->page_sz * msl->memseg_arr.len; - - if (msl->base_va == wa->va_addr && - len == wa->len) { - struct rte_memseg_list *found_msl; - int msl_idx, ret; - - /* msl is const */ - msl_idx = msl - mcfg->memsegs; - found_msl = &mcfg->memsegs[msl_idx]; - - if (wa->attach) { - ret = rte_fbarray_attach(&found_msl->memseg_arr); - } else { - /* notify all subscribers that a memory area is about to - * be removed - */ - eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE, - msl->base_va, msl->len); - ret = rte_fbarray_detach(&found_msl->memseg_arr); - } - - if (ret < 0) { - wa->result = -rte_errno; - } else { - /* notify all subscribers that a new memory area was - * added - */ - if (wa->attach) - eal_memalloc_mem_event_notify( - RTE_MEM_EVENT_ALLOC, - msl->base_va, msl->len); - wa->result = 0; - } - return 1; - } - return 0; -} - static int sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach) { - struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; struct malloc_heap *heap = NULL; - struct sync_mem_walk_arg wa; + struct rte_memseg_list *msl; int ret; if (heap_name == NULL || va_addr == NULL || len == 0 || @@ -489,7 +511,7 @@ sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach) rte_errno = EINVAL; return -1; } - rte_rwlock_read_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_lock(); /* find our heap */ heap = find_named_heap(heap_name); @@ -506,21 +528,38 @@ sync_memory(const char *heap_name, void *va_addr, size_t len, bool attach) } /* find corresponding memseg list to sync to */ - wa.va_addr = va_addr; - wa.len = len; - wa.result = -ENOENT; /* fail unless explicitly told to succeed */ - wa.attach = attach; - - /* we're already holding a read lock */ - rte_memseg_list_walk_thread_unsafe(sync_mem_walk, &wa); - - if (wa.result < 0) { - rte_errno = -wa.result; + msl = malloc_heap_find_external_seg(va_addr, len); + if (msl == NULL) { ret = -1; - } else - ret = 0; + goto unlock; + } + + if (attach) { + ret = rte_fbarray_attach(&msl->memseg_arr); + if (ret == 0) { + /* notify all subscribers that a new memory area was + * added. + */ + eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC, + va_addr, len); + } else { + ret = -1; + goto unlock; + } + } else { + /* notify all subscribers that a memory area is about to + * be removed. + */ + eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE, + msl->base_va, msl->len); + ret = rte_fbarray_detach(&msl->memseg_arr); + if (ret < 0) { + ret = -1; + goto unlock; + } + } unlock: - rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_read_unlock(); return ret; } @@ -553,7 +592,7 @@ rte_malloc_heap_create(const char *heap_name) /* check if there is space in the heap list, or if heap with this name * already exists. */ - rte_rwlock_write_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_lock(); for (i = 0; i < RTE_MAX_HEAPS; i++) { struct malloc_heap *tmp = &mcfg->malloc_heaps[i]; @@ -582,7 +621,7 @@ rte_malloc_heap_create(const char *heap_name) /* we're sure that we can create a new heap, so do it */ ret = malloc_heap_create(heap, heap_name); unlock: - rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_unlock(); return ret; } @@ -590,7 +629,6 @@ unlock: int rte_malloc_heap_destroy(const char *heap_name) { - struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config; struct malloc_heap *heap = NULL; int ret; @@ -601,7 +639,7 @@ rte_malloc_heap_destroy(const char *heap_name) rte_errno = EINVAL; return -1; } - rte_rwlock_write_lock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_lock(); /* start from non-socket heaps */ heap = find_named_heap(heap_name); @@ -625,7 +663,7 @@ rte_malloc_heap_destroy(const char *heap_name) if (ret < 0) rte_spinlock_unlock(&heap->lock); unlock: - rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock); + rte_mcfg_mem_write_unlock(); return ret; }