summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAzat Khuzhin <a3at.mail@gmail.com>2022-07-03 20:23:59 +0300
committerQi Wang <interwq@gmail.com>2022-07-11 15:27:51 -0700
commitcb578bbe01326bfc4a7b676f6921189d84518f03 (patch)
treec658f4e18a680f09e1567697e8951818522689db
parenta9215bf18aed1a1e59cbc7dfb9a0f018697d491d (diff)
downloadjemalloc-cb578bbe01326bfc4a7b676f6921189d84518f03.tar.gz
Fix possible "nmalloc >= ndalloc" assertion
In arena_stats_merge() first nmalloc was read, and after ndalloc. However with this order, it is possible for some thread to incement ndalloc in between, and then nmalloc < ndalloc, and assertion will fail, like again found by ClickHouse CI [1] (even after #2234). [1]: https://github.com/ClickHouse/ClickHouse/issues/31531 Swap the order to avoid possible assertion. Cc: @interwq Follow-up for: #2234
-rw-r--r--src/arena.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/src/arena.c b/src/arena.c
index 857b27c5..1ab2775e 100644
--- a/src/arena.c
+++ b/src/arena.c
@@ -106,18 +106,21 @@ arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
astats->metadata_thp += metadata_thp;
for (szind_t i = 0; i < SC_NSIZES - SC_NBINS; i++) {
- uint64_t nmalloc = locked_read_u64(tsdn,
- LOCKEDINT_MTX(arena->stats.mtx),
- &arena->stats.lstats[i].nmalloc);
- locked_inc_u64_unsynchronized(&lstats[i].nmalloc, nmalloc);
- astats->nmalloc_large += nmalloc;
-
+ /* ndalloc should be read before nmalloc,
+ * since otherwise it is possible for ndalloc to be incremented,
+ * and the following can become true: ndalloc > nmalloc */
uint64_t ndalloc = locked_read_u64(tsdn,
LOCKEDINT_MTX(arena->stats.mtx),
&arena->stats.lstats[i].ndalloc);
locked_inc_u64_unsynchronized(&lstats[i].ndalloc, ndalloc);
astats->ndalloc_large += ndalloc;
+ uint64_t nmalloc = locked_read_u64(tsdn,
+ LOCKEDINT_MTX(arena->stats.mtx),
+ &arena->stats.lstats[i].nmalloc);
+ locked_inc_u64_unsynchronized(&lstats[i].nmalloc, nmalloc);
+ astats->nmalloc_large += nmalloc;
+
uint64_t nrequests = locked_read_u64(tsdn,
LOCKEDINT_MTX(arena->stats.mtx),
&arena->stats.lstats[i].nrequests);