From 2e5899c1299125c17fc428026a364368ff1531ed Mon Sep 17 00:00:00 2001 From: David Goldblatt Date: Thu, 12 Mar 2020 12:42:10 -0700 Subject: [PATCH] Stats: Fix tcache_bytes reporting. Previously, large allocations in tcaches would have their sizes reduced during stats estimation. Added a test, which fails before this change but passes now. This fixes a bug introduced in 593484661261c20f75557279931eb2d9ca165185, which was itself fixing a bug introduced in 9c0549007dcb64f4ff35d37390a9a6a8d3cea880. --- src/arena.c | 3 ++- test/unit/stats.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/arena.c b/src/arena.c index 7f7c27fb..d4b69798 100644 --- a/src/arena.c +++ b/src/arena.c @@ -207,7 +207,8 @@ arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads, cache_bin_t *tbin = &descriptor->bins_large[i]; arena_stats_accum_zu(&astats->tcache_bytes, cache_bin_ncached_get(tbin, - &tcache_bin_info[i + SC_NBINS]) * sz_index2size(i)); + &tcache_bin_info[i + SC_NBINS]) + * sz_index2size(i + SC_NBINS)); } } malloc_mutex_prof_read(tsdn, diff --git a/test/unit/stats.c b/test/unit/stats.c index f4ac154d..20a32ddf 100644 --- a/test/unit/stats.c +++ b/test/unit/stats.c @@ -1,5 +1,8 @@ #include "test/jemalloc_test.h" +#define STRINGIFY_HELPER(x) #x +#define STRINGIFY(x) STRINGIFY_HELPER(x) + TEST_BEGIN(test_stats_summary) { size_t sz, allocated, active, resident, mapped; int expected = config_stats ? 0 : ENOENT; @@ -361,6 +364,50 @@ TEST_BEGIN(test_stats_arenas_lextents) { } TEST_END +static void +test_tcache_bytes_for_usize(size_t usize) { + uint64_t epoch; + size_t tcache_bytes; + size_t sz = sizeof(tcache_bytes); + + void *ptr = mallocx(usize, 0); + + expect_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)), + 0, "Unexpected mallctl() failure"); + assert_d_eq(mallctl( + "stats.arenas." STRINGIFY(MALLCTL_ARENAS_ALL) ".tcache_bytes", + &tcache_bytes, &sz, NULL, 0), 0, "Unexpected mallctl failure"); + size_t tcache_bytes_before = tcache_bytes; + dallocx(ptr, 0); + + expect_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)), + 0, "Unexpected mallctl() failure"); + assert_d_eq(mallctl( + "stats.arenas." STRINGIFY(MALLCTL_ARENAS_ALL) ".tcache_bytes", + &tcache_bytes, &sz, NULL, 0), 0, "Unexpected mallctl failure"); + size_t tcache_bytes_after = tcache_bytes; + assert_zu_eq(tcache_bytes_after - tcache_bytes_before, + usize, "Incorrectly attributed a free"); +} + +TEST_BEGIN(test_stats_tcache_bytes_small) { + test_skip_if(!config_stats); + test_skip_if(!opt_tcache); + test_skip_if((ZU(1) << opt_lg_tcache_max) < SC_SMALL_MAXCLASS); + + test_tcache_bytes_for_usize(SC_SMALL_MAXCLASS); +} +TEST_END + +TEST_BEGIN(test_stats_tcache_bytes_large) { + test_skip_if(!config_stats); + test_skip_if(!opt_tcache); + test_skip_if((ZU(1) << opt_lg_tcache_max) < SC_LARGE_MINCLASS); + + test_tcache_bytes_for_usize(SC_LARGE_MINCLASS); +} +TEST_END + int main(void) { return test_no_reentrancy( @@ -370,5 +417,7 @@ main(void) { test_stats_arenas_small, test_stats_arenas_large, test_stats_arenas_bins, - test_stats_arenas_lextents); + test_stats_arenas_lextents, + test_stats_tcache_bytes_small, + test_stats_tcache_bytes_large); }