From 09d7bdb314ec4d6a8618d6958809b540f8d3cff6 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Tue, 7 Jun 2016 14:00:58 -0700 Subject: Propagate tsdn to default chunk hooks. This avoids bootstrapping issues for configurations that require allocation during tsd initialization. This resolves #390. --- src/chunk.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/src/chunk.c b/src/chunk.c index adc666f..bff5908 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -421,15 +421,11 @@ chunk_arena_get(tsdn_t *tsdn, unsigned arena_ind) } static void * -chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, - bool *commit, unsigned arena_ind) +chunk_alloc_default_impl(tsdn_t *tsdn, arena_t *arena, void *new_addr, + size_t size, size_t alignment, bool *zero, bool *commit) { void *ret; - tsdn_t *tsdn; - arena_t *arena; - tsdn = tsdn_fetch(); - arena = chunk_arena_get(tsdn, arena_ind); ret = chunk_alloc_core(tsdn, arena, new_addr, size, alignment, zero, commit, arena->dss_prec); if (ret == NULL) @@ -441,6 +437,20 @@ chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, } static void * +chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, + bool *commit, unsigned arena_ind) +{ + tsdn_t *tsdn; + arena_t *arena; + + tsdn = tsdn_fetch(); + arena = chunk_arena_get(tsdn, arena_ind); + + return (chunk_alloc_default_impl(tsdn, arena, new_addr, size, alignment, + zero, commit)); +} + +static void * chunk_alloc_retained(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit) { @@ -472,8 +482,15 @@ chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, ret = chunk_alloc_retained(tsdn, arena, chunk_hooks, new_addr, size, alignment, zero, commit); if (ret == NULL) { - ret = chunk_hooks->alloc(new_addr, size, alignment, zero, - commit, arena->ind); + if (chunk_hooks->alloc == chunk_alloc_default) { + /* Call directly to propagate tsdn. */ + ret = chunk_alloc_default_impl(tsdn, arena, new_addr, + size, alignment, zero, commit); + } else { + ret = chunk_hooks->alloc(new_addr, size, alignment, + zero, commit, arena->ind); + } + if (ret == NULL) return (NULL); } @@ -591,19 +608,30 @@ chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, } static bool -chunk_dalloc_default(void *chunk, size_t size, bool committed, - unsigned arena_ind) +chunk_dalloc_default_impl(tsdn_t *tsdn, void *chunk, size_t size) { - if (!have_dss || !chunk_in_dss(tsdn_fetch(), chunk)) + if (!have_dss || !chunk_in_dss(tsdn, chunk)) return (chunk_dalloc_mmap(chunk, size)); return (true); } +static bool +chunk_dalloc_default(void *chunk, size_t size, bool committed, + unsigned arena_ind) +{ + tsdn_t *tsdn; + + tsdn = tsdn_fetch(); + + return (chunk_dalloc_default_impl(tsdn, chunk, size)); +} + void chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk, size_t size, bool zeroed, bool committed) { + bool err; assert(chunk != NULL); assert(CHUNK_ADDR2BASE(chunk) == chunk); @@ -612,7 +640,13 @@ chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, chunk_hooks_assure_initialized(tsdn, arena, chunk_hooks); /* Try to deallocate. */ - if (!chunk_hooks->dalloc(chunk, size, committed, arena->ind)) + if (chunk_hooks->dalloc == chunk_dalloc_default) { + /* Call directly to propagate tsdn. */ + err = chunk_dalloc_default_impl(tsdn, chunk, size); + } else + err = chunk_hooks->dalloc(chunk, size, committed, arena->ind); + + if (!err) return; /* Try to decommit; purge if that fails. */ if (committed) { @@ -681,26 +715,34 @@ chunk_split_default(void *chunk, size_t size, size_t size_a, size_t size_b, } static bool -chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, - bool committed, unsigned arena_ind) +chunk_merge_default_impl(tsdn_t *tsdn, void *chunk_a, void *chunk_b) { if (!maps_coalesce) return (true); - if (have_dss) { - tsdn_t *tsdn = tsdn_fetch(); - if (chunk_in_dss(tsdn, chunk_a) != chunk_in_dss(tsdn, chunk_b)) - return (true); - } + if (have_dss && chunk_in_dss(tsdn, chunk_a) != chunk_in_dss(tsdn, + chunk_b)) + return (true); return (false); } +static bool +chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, + bool committed, unsigned arena_ind) +{ + tsdn_t *tsdn; + + tsdn = tsdn_fetch(); + + return (chunk_merge_default_impl(tsdn, chunk_a, chunk_b)); +} + static rtree_node_elm_t * chunks_rtree_node_alloc(size_t nelms) { - return ((rtree_node_elm_t *)base_alloc(tsdn_fetch(), nelms * + return ((rtree_node_elm_t *)base_alloc(TSDN_NULL, nelms * sizeof(rtree_node_elm_t))); } -- cgit v0.12 From 48384dc2d841bac9ab1e1ef24addbccabed43c20 Mon Sep 17 00:00:00 2001 From: Elliot Ronaghan Date: Fri, 27 May 2016 16:20:23 -0700 Subject: Fix mixed decl in nstime.c Fix mixed decl in the gettimeofday() branch of nstime_update() --- src/nstime.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/nstime.c b/src/nstime.c index 26e49dc..aad2c26 100644 --- a/src/nstime.c +++ b/src/nstime.c @@ -128,9 +128,11 @@ nstime_update(nstime_t *time) time->ns = ts.tv_sec * BILLION + ts.tv_nsec; } #else - struct timeval tv; - gettimeofday(&tv, NULL); - time->ns = tv.tv_sec * BILLION + tv.tv_usec * 1000; + { + struct timeval tv; + gettimeofday(&tv, NULL); + time->ns = tv.tv_sec * BILLION + tv.tv_usec * 1000; + } #endif /* Handle non-monotonic clocks. */ -- cgit v0.12 From 05a9e4ac651eb0c728e83fd883425c4894a2ae2b Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Tue, 7 Jun 2016 14:19:50 -0700 Subject: Fix potential VM map fragmentation regression. Revert 245ae6036c09cc11a72fab4335495d95cddd5beb (Support --with-lg-page values larger than actual page size.), because it could cause VM map fragmentation if the kernel grows mmap()ed memory downward. This resolves #391. --- include/jemalloc/internal/jemalloc_internal.h.in | 4 ++-- src/arena.c | 2 +- src/chunk_mmap.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in index 51bf897..8f82edd 100644 --- a/include/jemalloc/internal/jemalloc_internal.h.in +++ b/include/jemalloc/internal/jemalloc_internal.h.in @@ -754,7 +754,7 @@ sa2u(size_t size, size_t alignment) * Calculate the size of the over-size run that arena_palloc() * would need to allocate in order to guarantee the alignment. */ - if (usize + large_pad + alignment <= arena_maxrun) + if (usize + large_pad + alignment - PAGE <= arena_maxrun) return (usize); } @@ -784,7 +784,7 @@ sa2u(size_t size, size_t alignment) * Calculate the multi-chunk mapping that huge_palloc() would need in * order to guarantee the alignment. */ - if (usize + alignment < usize) { + if (usize + alignment - PAGE < usize) { /* size_t overflow. */ return (0); } diff --git a/src/arena.c b/src/arena.c index c605bcd..ce62590 100644 --- a/src/arena.c +++ b/src/arena.c @@ -2687,7 +2687,7 @@ arena_palloc_large(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment, return (NULL); alignment = PAGE_CEILING(alignment); - alloc_size = usize + large_pad + alignment; + alloc_size = usize + large_pad + alignment - PAGE; malloc_mutex_lock(tsdn, &arena->lock); run = arena_run_alloc_large(tsdn, arena, alloc_size, false); diff --git a/src/chunk_mmap.c b/src/chunk_mmap.c index f95ae75..73fc497 100644 --- a/src/chunk_mmap.c +++ b/src/chunk_mmap.c @@ -9,7 +9,7 @@ chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit) void *ret; size_t alloc_size; - alloc_size = size + alignment; + alloc_size = size + alignment - PAGE; /* Beware size_t wrap-around. */ if (alloc_size < size) return (NULL); -- cgit v0.12 From 9de0094e6e085f186afd608ad874402a589ed576 Mon Sep 17 00:00:00 2001 From: Elliot Ronaghan Date: Tue, 7 Jun 2016 14:27:24 -0700 Subject: Fix a Valgrind regression in calloc(). This regression was caused by 3ef51d7f733ac6432e80fa902a779ab5b98d74f6 (Optimize the fast paths of calloc() and [m,d,sd]allocx().). --- src/jemalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jemalloc.c b/src/jemalloc.c index 40eb2ea..4d7c481 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -1739,7 +1739,7 @@ je_calloc(size_t num, size_t size) ret = ialloc_body(num_size, true, &tsdn, &usize, true); ialloc_post_check(ret, tsdn, usize, "calloc", true, true); UTRACE(0, num_size, ret); - JEMALLOC_VALGRIND_MALLOC(ret != NULL, tsdn, ret, usize, false); + JEMALLOC_VALGRIND_MALLOC(ret != NULL, tsdn, ret, usize, true); } return (ret); -- cgit v0.12 From c7d52980275b22f64c672ebaede28dc95d4f1820 Mon Sep 17 00:00:00 2001 From: Elliot Ronaghan Date: Tue, 7 Jun 2016 14:30:39 -0700 Subject: Fix a Valgrind regression in chunk_alloc_wrapper(). This regression was caused by d412624b25eed2b5c52b7d94a71070d3aab03cb4 (Move retaining out of default chunk hooks). --- src/chunk.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/chunk.c b/src/chunk.c index bff5908..f292c98 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -493,10 +493,12 @@ chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, if (ret == NULL) return (NULL); + + if (config_valgrind && chunk_hooks->alloc != + chunk_alloc_default) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, chunksize); } - if (config_valgrind && chunk_hooks->alloc != chunk_alloc_default) - JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, chunksize); return (ret); } -- cgit v0.12 From a7fdcc8b09d197d64d1772d1e8025add44f48f0a Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Tue, 17 May 2016 17:12:13 -0700 Subject: Fix opt_zero-triggered in-place huge reallocation zeroing. Fix huge_ralloc_no_move_expand() to update the extent's zeroed attribute based on the intersection of the previous value and that of the newly merged trailing extent. --- src/huge.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/huge.c b/src/huge.c index 1aa02a0..3a2877c 100644 --- a/src/huge.c +++ b/src/huge.c @@ -262,19 +262,19 @@ huge_ralloc_no_move_expand(tsdn_t *tsdn, void *ptr, size_t oldsize, malloc_mutex_unlock(tsdn, &arena->huge_mtx); /* - * Copy zero into is_zeroed_chunk and pass the copy to chunk_alloc(), so - * that it is possible to make correct junk/zero fill decisions below. + * Use is_zeroed_chunk to detect whether the trailing memory is zeroed, + * update extent's zeroed field, and zero as necessary. */ - is_zeroed_chunk = zero; - + is_zeroed_chunk = false; if (arena_chunk_ralloc_huge_expand(tsdn, arena, ptr, oldsize, usize, &is_zeroed_chunk)) return (true); malloc_mutex_lock(tsdn, &arena->huge_mtx); - /* Update the size of the huge allocation. */ huge_node_unset(ptr, node); extent_node_size_set(node, usize); + extent_node_zeroed_set(node, extent_node_zeroed_get(node) && + is_zeroed_chunk); huge_node_reset(tsdn, ptr, node); malloc_mutex_unlock(tsdn, &arena->huge_mtx); -- cgit v0.12 From 20cd2de5ef622c3af8b3e4aba897aff7ddd451a7 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Wed, 1 Jun 2016 16:17:31 -0700 Subject: Add a missing prof_alloc_rollback() call. In the case where prof_alloc_prep() is called with an over-estimate of allocation size, and sampling doesn't end up being triggered, the tctx must be discarded. --- include/jemalloc/internal/prof.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/jemalloc/internal/prof.h b/include/jemalloc/internal/prof.h index 691e153..21dff5f 100644 --- a/include/jemalloc/internal/prof.h +++ b/include/jemalloc/internal/prof.h @@ -513,6 +513,7 @@ prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx, * though its actual usize was insufficient to cross the * sample threshold. */ + prof_alloc_rollback(tsd, tctx, true); tctx = (prof_tctx_t *)(uintptr_t)1U; } } -- cgit v0.12 From fa09fe798aa4f9f4f503059c9146227df2b8c18d Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Wed, 1 Jun 2016 16:19:22 -0700 Subject: Fix rallocx() sampling code to not eagerly commit sampler update. rallocx() for an alignment-constrained request may end up with a smaller-than-worst-case size if in-place reallocation succeeds due to serendipitous alignment. In such cases, sampling may not happen. --- src/jemalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/jemalloc.c b/src/jemalloc.c index 4d7c481..5d1f493 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -2222,7 +2222,7 @@ irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size, prof_active = prof_active_get_unlocked(); old_tctx = prof_tctx_get(tsd_tsdn(tsd), old_ptr); - tctx = prof_alloc_prep(tsd, *usize, prof_active, true); + tctx = prof_alloc_prep(tsd, *usize, prof_active, false); if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) { p = irallocx_prof_sample(tsd, old_ptr, old_usize, *usize, alignment, zero, tcache, arena, tctx); @@ -2231,7 +2231,7 @@ irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size, tcache, arena); } if (unlikely(p == NULL)) { - prof_alloc_rollback(tsd, tctx, true); + prof_alloc_rollback(tsd, tctx, false); return (NULL); } @@ -2246,7 +2246,7 @@ irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size, */ *usize = isalloc(tsd_tsdn(tsd), p, config_prof); } - prof_realloc(tsd, p, *usize, tctx, prof_active, true, old_ptr, + prof_realloc(tsd, p, *usize, tctx, prof_active, false, old_ptr, old_usize, old_tctx); return (p); -- cgit v0.12 From 5271b673b2e93dd655fde6f2ee1ea849da5cb3d2 Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Tue, 7 Jun 2016 14:40:43 -0700 Subject: Update ChangeLog for 4.2.1. --- ChangeLog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 926209e..ed62e0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,17 @@ brevity. Much more detail can be found in the git revision history: https://github.com/jemalloc/jemalloc +* 4.2.1 (June 8, 2016) + + Bug fixes: + - Fix bootstrapping issues for configurations that require allocation during + tsd initialization (e.g. --disable-tls). (@cferris1000, @jasone) + - Fix gettimeofday() version of nstime_update(). (@ronawho) + - Fix Valgrind regressions in calloc() and chunk_alloc_wrapper(). (@ronawho) + - Fix potential VM map fragmentation regression. (@jasone) + - Fix opt_zero-triggered in-place huge reallocation zeroing. (@jasone) + - Fix heap profiling context leaks in reallocation edge cases. (@jasone) + * 4.2.0 (May 12, 2016) New features: -- cgit v0.12