X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fvppinfra%2Fdlmalloc.c;h=cc5915a3852f397b42471f0c75b4f3b431f21a42;hb=6531cf5d1cffab8690c42847eef4f00f3018bb70;hp=9ed1e04f77697097ed408151c9bd6119cba65056;hpb=d9818dd68c162079f3ddb5443a78d0d91d55d0fe;p=vpp.git diff --git a/src/vppinfra/dlmalloc.c b/src/vppinfra/dlmalloc.c index 9ed1e04f776..cc5915a3852 100644 --- a/src/vppinfra/dlmalloc.c +++ b/src/vppinfra/dlmalloc.c @@ -5,6 +5,7 @@ comments, complaints, performance data, etc to dl@cs.oswego.edu */ +#include #include /*------------------------------ internal #includes ---------------------- */ @@ -459,6 +460,7 @@ static FORCEINLINE void x86_clear_lock(int* sl) { #if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0 /* Plain spin locks use single word (embedded in malloc_states) */ +__clib_nosanitize_addr static int spin_acquire_lock(int *sl) { int spins = 0; while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) { @@ -1247,7 +1249,7 @@ static struct malloc_state _gm_; #define disable_expand(M) ((M)->mflags |= USE_NOEXPAND_BIT) #define use_trace(M) ((M)->mflags & USE_TRACE_BIT) #define enable_trace(M) ((M)->mflags |= USE_TRACE_BIT) -#define disable_trace(M) ((M)->mflags |= USE_TRACE_BIT) +#define disable_trace(M) ((M)->mflags &= ~USE_TRACE_BIT) #define set_lock(M,L)\ ((M)->mflags = (L)?\ @@ -1284,6 +1286,7 @@ static struct malloc_state _gm_; ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) /* Return segment holding given address */ +__clib_nosanitize_addr static msegmentptr segment_holding(mstate m, char* addr) { msegmentptr sp = &m->seg; for (;;) { @@ -1295,6 +1298,7 @@ static msegmentptr segment_holding(mstate m, char* addr) { } /* Return true if segment contains a segment link */ +__clib_nosanitize_addr static int has_segment_link(mstate m, msegmentptr ss) { msegmentptr sp = &m->seg; for (;;) { @@ -1612,6 +1616,7 @@ static size_t traverse_and_check(mstate m); #if (FOOTERS && !INSECURE) /* Check if (alleged) mstate m has expected magic field */ +__clib_nosanitize_addr static inline int ok_magic (const mstate m) { @@ -2078,6 +2083,7 @@ static void do_check_malloc_state(mstate m) { /* ----------------------------- statistics ------------------------------ */ #if !NO_MALLINFO +__clib_nosanitize_addr static struct dlmallinfo internal_mallinfo(mstate m) { struct dlmallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; ensure_initialization(); @@ -2487,6 +2493,7 @@ static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) { /* -------------------------- mspace management -------------------------- */ /* Initialize top chunk and its size */ +__clib_nosanitize_addr static void init_top(mstate m, mchunkptr p, size_t psize) { /* Ensure alignment */ size_t offset = align_offset(chunk2mem(p)); @@ -2531,6 +2538,7 @@ static void reset_on_error(mstate m) { #endif /* PROCEED_ON_ERROR */ /* Allocate chunk and prepend remainder with chunk in successor base. */ +__clib_nosanitize_addr static void* prepend_alloc(mstate m, char* newbase, char* oldbase, size_t nb) { mchunkptr p = align_as_chunk(newbase); @@ -2573,6 +2581,7 @@ static void* prepend_alloc(mstate m, char* newbase, char* oldbase, } /* Add a segment to hold a new noncontiguous region */ +__clib_nosanitize_addr static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { /* Determine locations and sizes of segment, fenceposts, old top */ char* old_top = (char*)m->top; @@ -2628,6 +2637,7 @@ static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { /* -------------------------- System allocation -------------------------- */ /* Get memory from system using MORECORE or MMAP */ +__clib_nosanitize_addr static void* sys_alloc(mstate m, size_t nb) { char* tbase = CMFAIL; size_t tsize = 0; @@ -2842,6 +2852,7 @@ static void* sys_alloc(mstate m, size_t nb) { /* ----------------------- system deallocation -------------------------- */ /* Unmap and unlink any mmapped segments that don't contain used chunks */ +__clib_nosanitize_addr static size_t release_unused_segments(mstate m) { size_t released = 0; int nsegs = 0; @@ -2889,6 +2900,7 @@ static size_t release_unused_segments(mstate m) { return released; } +__clib_nosanitize_addr static int sys_trim(mstate m, size_t pad) { size_t released = 0; ensure_initialization(); @@ -2957,6 +2969,7 @@ static int sys_trim(mstate m, size_t pad) { /* Consolidate and bin a chunk. Differs from exported versions of free mainly in that the chunk need not be marked as inuse. */ +__clib_nosanitize_addr static void dispose_chunk(mstate m, mchunkptr p, size_t psize) { mchunkptr next = chunk_plus_offset(p, psize); if (!pinuse(p)) { @@ -3028,6 +3041,7 @@ static void dispose_chunk(mstate m, mchunkptr p, size_t psize) { /* ---------------------------- malloc --------------------------- */ /* allocate a large request from the best fitting chunk in a treebin */ +__clib_nosanitize_addr static void* tmalloc_large(mstate m, size_t nb) { tchunkptr v = 0; size_t rsize = -nb; /* Unsigned negation */ @@ -3099,6 +3113,7 @@ static void* tmalloc_large(mstate m, size_t nb) { } /* allocate a small request from the best fitting chunk in a treebin */ +__clib_nosanitize_addr static void* tmalloc_small(mstate m, size_t nb) { tchunkptr t, v; size_t rsize; @@ -3405,7 +3420,7 @@ void* dlcalloc(size_t n_elements, size_t elem_size) { /* ------------ Internal support for realloc, memalign, etc -------------- */ /* Try to realloc; only in-place unless can_move true */ -static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, +static __clib_nosanitize_addr mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, int can_move) { mchunkptr newp = 0; size_t oldsize = chunksize(p); @@ -3484,6 +3499,7 @@ static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb, return newp; } +__clib_nosanitize_addr static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { void* mem = 0; if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ @@ -4066,6 +4082,7 @@ int mspace_track_large_chunks(mspace msp, int enable) { return ret; } +__clib_nosanitize_addr size_t destroy_mspace(mspace msp) { size_t freed = 0; mstate ms = (mstate)msp; @@ -4093,7 +4110,7 @@ void mspace_get_address_and_size (mspace msp, char **addrp, size_t *sizep) { mstate ms; msegment *this_seg; - + ms = (mstate)msp; this_seg = &ms->seg; @@ -4101,6 +4118,7 @@ void mspace_get_address_and_size (mspace msp, char **addrp, size_t *sizep) *sizep = this_seg->size; } +__clib_nosanitize_addr int mspace_is_heap_object (mspace msp, void *p) { msegment *this_seg; @@ -4126,6 +4144,7 @@ int mspace_is_heap_object (mspace msp, void *p) return 0; } +__clib_nosanitize_addr void *mspace_least_addr (mspace msp) { mstate ms = (mstate) msp; @@ -4139,6 +4158,7 @@ void mspace_disable_expand (mspace msp) disable_expand (ms); } +__clib_nosanitize_addr int mspace_enable_disable_trace (mspace msp, int enable) { mstate ms = (mstate)msp; @@ -4155,9 +4175,20 @@ int mspace_enable_disable_trace (mspace msp, int enable) return (was_enabled); } -void* mspace_get_aligned (mspace msp, +__clib_nosanitize_addr +int mspace_is_traced (mspace msp) +{ + mstate ms = (mstate)msp; + + if (use_trace(ms)) + return 1; + return 0; +} + +__clib_nosanitize_addr +void* mspace_get_aligned (mspace msp, unsigned long n_user_data_bytes, - unsigned long align, + unsigned long align, unsigned long align_offset) { char *rv; unsigned long searchp; @@ -4165,46 +4196,25 @@ void* mspace_get_aligned (mspace msp, mstate ms = (mstate)msp; /* - * Allocate space for the "Where's Waldo?" pointer + * Allocate space for the "Where's Waldo?" pointer * the base of the dlmalloc object */ n_user_data_bytes += sizeof(unsigned); - - /* - * Alignment requests less than the size of an mmx vector are ignored - */ - if (align < 16) { - rv = mspace_malloc (msp, n_user_data_bytes); - if (rv == 0) - return rv; - - if (use_trace(ms)) { - mchunkptr p = mem2chunk(rv); - size_t psize = chunksize(p); - - mheap_get_trace ((unsigned long)rv + sizeof (unsigned), psize); - } - - wwp = (unsigned *)rv; - *wwp = 0; - rv += sizeof (unsigned); - - return rv; - } + align = align < MALLOC_ALIGNMENT ? MALLOC_ALIGNMENT : align; /* * Alignment requests greater than 4K must be at offset zero, * and must be freed using mspace_free_no_offset - or never freed - * since the "Where's Waldo?" pointer would waste too much space. - * - * Waldo is the address of the chunk of memory returned by mspace_malloc, + * + * Waldo is the address of the chunk of memory returned by mspace_malloc, * which we need later to call mspace_free... */ if (align > 4<<10 || align_offset == ~0UL) { n_user_data_bytes -= sizeof(unsigned); assert(align_offset == 0); rv = internal_memalign(ms, (size_t)align, n_user_data_bytes); - + /* Trace the allocation */ if (rv && use_trace(ms)) { mchunkptr p = mem2chunk(rv); @@ -4250,11 +4260,12 @@ void* mspace_get_aligned (mspace msp, if (use_trace(ms)) { mchunkptr p = mem2chunk(rv); size_t psize = chunksize(p); - mheap_get_trace ((unsigned long)rv, psize); + mheap_get_trace (searchp, psize); } return (void *) searchp; } +__clib_nosanitize_addr void mspace_put (mspace msp, void *p_arg) { char *object_header; @@ -4278,7 +4289,7 @@ void mspace_put (mspace msp, void *p_arg) mheap_put_trace ((unsigned long)p_arg, psize); } -#if CLIB_DEBUG > 0 +#if CLIB_DEBUG > 0 && !defined(CLIB_SANITIZE_ADDR) /* Poison the object */ { size_t psize = mspace_usable_size (object_header); @@ -4304,6 +4315,7 @@ void mspace_put_no_offset (mspace msp, void *p_arg) mspace_free (msp, p_arg); } +__clib_nosanitize_addr size_t mspace_usable_size_with_delta (const void *p) { size_t usable_size; @@ -4329,6 +4341,7 @@ size_t mspace_usable_size_with_delta (const void *p) versions. This is not so nice but better than the alternatives. */ +__clib_nosanitize_addr void* mspace_malloc(mspace msp, size_t bytes) { mstate ms = (mstate)msp; if (!ok_magic(ms)) { @@ -4443,6 +4456,7 @@ void* mspace_malloc(mspace msp, size_t bytes) { return 0; } +__clib_nosanitize_addr void mspace_free(mspace msp, void* mem) { if (mem != 0) { mchunkptr p = mem2chunk(mem); @@ -4609,6 +4623,7 @@ void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { return mem; } +__clib_nosanitize_addr void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) { void* mem = 0; if (oldmem != 0) { @@ -4641,6 +4656,7 @@ void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) { return mem; } +__clib_nosanitize_addr void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { mstate ms = (mstate)msp; if (!ok_magic(ms)) { @@ -4780,6 +4796,7 @@ size_t mspace_set_footprint_limit(mspace msp, size_t bytes) { } #if !NO_MALLINFO +__clib_nosanitize_addr struct dlmallinfo mspace_mallinfo(mspace msp) { mstate ms = (mstate)msp; if (!ok_magic(ms)) { @@ -4789,6 +4806,7 @@ struct dlmallinfo mspace_mallinfo(mspace msp) { } #endif /* NO_MALLINFO */ +__clib_nosanitize_addr size_t mspace_usable_size(const void* mem) { if (mem != 0) { mchunkptr p = mem2chunk(mem);