From 8dd5ea87cac39d9a90dbe40d13267ec02df0214c Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Thu, 3 Nov 2016 17:25:54 -0700 Subject: [PATCH] Fix extent_alloc_cache[_locked]() to support decommitted allocation. Fix extent_alloc_cache[_locked]() to support decommitted allocation, and use this ability in arena_stash_dirty(), so that decommitted extents are not needlessly committed during purging. In practice this does not happen on any currently supported systems, because both extent merging and decommit must be implemented; all supported systems implement one xor the other. --- include/jemalloc/internal/extent.h | 4 ++-- src/arena.c | 11 ++++++----- src/extent.c | 20 +++++++++----------- src/large.c | 4 ++-- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/include/jemalloc/internal/extent.h b/include/jemalloc/internal/extent.h index 08d30365..673cac2f 100644 --- a/include/jemalloc/internal/extent.h +++ b/include/jemalloc/internal/extent.h @@ -101,10 +101,10 @@ ph_proto(, extent_heap_, extent_heap_t, extent_t) extent_t *extent_alloc_cache_locked(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad, - size_t alignment, bool *zero, bool slab); + size_t alignment, bool *zero, bool *commit, bool slab); extent_t *extent_alloc_cache(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad, - size_t alignment, bool *zero, bool slab); + size_t alignment, bool *zero, bool *commit, bool slab); extent_t *extent_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad, size_t alignment, bool *zero, bool *commit, bool slab); diff --git a/src/arena.c b/src/arena.c index ce289594..fd3c5531 100644 --- a/src/arena.c +++ b/src/arena.c @@ -49,11 +49,12 @@ arena_extent_cache_alloc_locked(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad, size_t alignment, bool *zero, bool slab) { + bool commit = true; malloc_mutex_assert_owner(tsdn, &arena->lock); return (extent_alloc_cache(tsdn, arena, r_extent_hooks, new_addr, usize, - pad, alignment, zero, slab)); + pad, alignment, zero, &commit, slab)); } extent_t * @@ -681,7 +682,7 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, for (extent = qr_next(&arena->extents_dirty, qr_link); extent != &arena->extents_dirty; extent = next) { size_t npages; - bool zero; + bool zero, commit; UNUSED extent_t *textent; npages = extent_size_get(extent) >> LG_PAGE; @@ -691,9 +692,10 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, next = qr_next(extent, qr_link); /* Allocate. */ zero = false; + commit = false; textent = extent_alloc_cache_locked(tsdn, arena, r_extent_hooks, extent_base_get(extent), extent_size_get(extent), 0, PAGE, - &zero, false); + &zero, &commit, false); assert(textent == extent); assert(zero == extent_zeroed_get(extent)); extent_ring_remove(extent); @@ -943,9 +945,8 @@ arena_slab_alloc(tsdn_t *tsdn, arena_t *arena, szind_t binind, extent_t *slab; arena_slab_data_t *slab_data; extent_hooks_t *extent_hooks = EXTENT_HOOKS_INITIALIZER; - bool zero; + bool zero = false; - zero = false; slab = arena_extent_cache_alloc_locked(tsdn, arena, &extent_hooks, NULL, bin_info->slab_size, 0, PAGE, &zero, true); if (slab == NULL) { diff --git a/src/extent.c b/src/extent.c index 809777a1..ad78c879 100644 --- a/src/extent.c +++ b/src/extent.c @@ -517,8 +517,9 @@ extent_recycle(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, extent_usize_set(extent, usize); } - if (!extent_committed_get(extent) && extent_commit_wrapper(tsdn, arena, - r_extent_hooks, extent, 0, extent_size_get(extent))) { + if (commit && !extent_committed_get(extent) && + extent_commit_wrapper(tsdn, arena, r_extent_hooks, extent, 0, + extent_size_get(extent))) { if (!locked) malloc_mutex_unlock(tsdn, &arena->extents_mtx); extent_record(tsdn, arena, r_extent_hooks, extent_heaps, cache, @@ -590,44 +591,41 @@ extent_alloc_core(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size, static extent_t * extent_alloc_cache_impl(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, bool locked, void *new_addr, size_t usize, - size_t pad, size_t alignment, bool *zero, bool slab) + size_t pad, size_t alignment, bool *zero, bool *commit, bool slab) { extent_t *extent; - bool commit; assert(usize + pad != 0); assert(alignment != 0); - commit = true; extent = extent_recycle(tsdn, arena, r_extent_hooks, arena->extents_cached, locked, true, new_addr, usize, pad, - alignment, zero, &commit, slab); + alignment, zero, commit, slab); if (extent == NULL) return (NULL); - assert(commit); return (extent); } extent_t * extent_alloc_cache_locked(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad, - size_t alignment, bool *zero, bool slab) + size_t alignment, bool *zero, bool *commit, bool slab) { malloc_mutex_assert_owner(tsdn, &arena->extents_mtx); return (extent_alloc_cache_impl(tsdn, arena, r_extent_hooks, true, - new_addr, usize, pad, alignment, zero, slab)); + new_addr, usize, pad, alignment, zero, commit, slab)); } extent_t * extent_alloc_cache(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad, - size_t alignment, bool *zero, bool slab) + size_t alignment, bool *zero, bool *commit, bool slab) { return (extent_alloc_cache_impl(tsdn, arena, r_extent_hooks, false, - new_addr, usize, pad, alignment, zero, slab)); + new_addr, usize, pad, alignment, zero, commit, slab)); } static void * diff --git a/src/large.c b/src/large.c index 23af1830..1bae9399 100644 --- a/src/large.c +++ b/src/large.c @@ -143,8 +143,8 @@ large_ralloc_no_move_expand(tsdn_t *tsdn, extent_t *extent, size_t usize, extent_t *trail; if ((trail = arena_extent_cache_alloc(tsdn, arena, &extent_hooks, - extent_past_get(extent), trailsize, CACHELINE, &is_zeroed_trail)) - == NULL) { + extent_past_get(extent), trailsize, CACHELINE, &is_zeroed_trail)) == + NULL) { bool commit = true; if ((trail = extent_alloc_wrapper(tsdn, arena, &extent_hooks, extent_past_get(extent), trailsize, 0, CACHELINE,