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
This commit is contained in:
parent
a9215bf18a
commit
cb578bbe01
15
src/arena.c
15
src/arena.c
@ -106,18 +106,21 @@ arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
|
|||||||
astats->metadata_thp += metadata_thp;
|
astats->metadata_thp += metadata_thp;
|
||||||
|
|
||||||
for (szind_t i = 0; i < SC_NSIZES - SC_NBINS; i++) {
|
for (szind_t i = 0; i < SC_NSIZES - SC_NBINS; i++) {
|
||||||
uint64_t nmalloc = locked_read_u64(tsdn,
|
/* ndalloc should be read before nmalloc,
|
||||||
LOCKEDINT_MTX(arena->stats.mtx),
|
* since otherwise it is possible for ndalloc to be incremented,
|
||||||
&arena->stats.lstats[i].nmalloc);
|
* and the following can become true: ndalloc > nmalloc */
|
||||||
locked_inc_u64_unsynchronized(&lstats[i].nmalloc, nmalloc);
|
|
||||||
astats->nmalloc_large += nmalloc;
|
|
||||||
|
|
||||||
uint64_t ndalloc = locked_read_u64(tsdn,
|
uint64_t ndalloc = locked_read_u64(tsdn,
|
||||||
LOCKEDINT_MTX(arena->stats.mtx),
|
LOCKEDINT_MTX(arena->stats.mtx),
|
||||||
&arena->stats.lstats[i].ndalloc);
|
&arena->stats.lstats[i].ndalloc);
|
||||||
locked_inc_u64_unsynchronized(&lstats[i].ndalloc, ndalloc);
|
locked_inc_u64_unsynchronized(&lstats[i].ndalloc, ndalloc);
|
||||||
astats->ndalloc_large += 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,
|
uint64_t nrequests = locked_read_u64(tsdn,
|
||||||
LOCKEDINT_MTX(arena->stats.mtx),
|
LOCKEDINT_MTX(arena->stats.mtx),
|
||||||
&arena->stats.lstats[i].nrequests);
|
&arena->stats.lstats[i].nrequests);
|
||||||
|
Loading…
Reference in New Issue
Block a user