X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Frte_malloc.c;h=b119ebae363ef52aeabdfeeafd73d86cd57e1cf1;hb=cfe3aeb170b2f6277e6f96173599da51eab0654f;hp=0da5ad5e87231fab4f663ff44ff07ad986e8d544;hpb=1ccfeb7df780d7d74605ac2e16cab8aef163481d;p=dpdk.git diff --git a/lib/librte_eal/common/rte_malloc.c b/lib/librte_eal/common/rte_malloc.c index 0da5ad5e87..b119ebae36 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 @@ -74,7 +74,18 @@ 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 + return ptr; } /* @@ -105,13 +116,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,14 +131,21 @@ 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 && + + /* 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) 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; @@ -137,6 +155,15 @@ rte_realloc(void *ptr, size_t size, unsigned align) 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 +183,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 @@ -262,8 +279,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 +295,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; } @@ -340,11 +354,15 @@ rte_malloc_heap_memory_add(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; 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) { @@ -367,15 +385,16 @@ 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); rte_spinlock_unlock(&heap->lock); unlock: @@ -389,6 +408,7 @@ 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 || @@ -413,9 +433,19 @@ 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); @@ -423,63 +453,12 @@ 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 || @@ -506,23 +485,35 @@ 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 { - /* notify all subscribers that a new memory area was added */ - if (attach) + 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); - ret = 0; + } 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);