Fix missing release of acquired neighbor edata in extent_try_coalesce_impl

When emap_try_acquire_edata_neighbor returned a non-NULL neighbor but
the size check failed, the neighbor was never released from
extent_state_merging, making it permanently invisible to future
allocation and coalescing operations.

Release the neighbor when it doesn't meet the size requirement,
matching the pattern used in extent_recycle_extract.
This commit is contained in:
Slobodan Predolac 2026-03-27 10:04:43 -07:00
parent 3f6e63e86a
commit 675ab079e7
2 changed files with 73 additions and 18 deletions

View file

@ -916,15 +916,20 @@ extent_try_coalesce_impl(tsdn_t *tsdn, pac_t *pac, ehooks_t *ehooks,
size_t max_next_neighbor = max_size > edata_size_get(edata)
? max_size - edata_size_get(edata)
: 0;
if (next != NULL && edata_size_get(next) <= max_next_neighbor) {
if (!extent_coalesce(
tsdn, pac, ehooks, ecache, edata, next, true)) {
if (ecache->delay_coalesce) {
/* Do minimal coalescing. */
*coalesced = true;
return edata;
if (next != NULL) {
if (edata_size_get(next) > max_next_neighbor) {
emap_release_edata(
tsdn, pac->emap, next, ecache->state);
} else {
if (!extent_coalesce(tsdn, pac, ehooks, ecache,
edata, next, true)) {
if (ecache->delay_coalesce) {
/* Do minimal coalescing. */
*coalesced = true;
return edata;
}
again = true;
}
again = true;
}
}
@ -934,16 +939,21 @@ extent_try_coalesce_impl(tsdn_t *tsdn, pac_t *pac, ehooks_t *ehooks,
size_t max_prev_neighbor = max_size > edata_size_get(edata)
? max_size - edata_size_get(edata)
: 0;
if (prev != NULL && edata_size_get(prev) <= max_prev_neighbor) {
if (!extent_coalesce(tsdn, pac, ehooks, ecache, edata,
prev, false)) {
edata = prev;
if (ecache->delay_coalesce) {
/* Do minimal coalescing. */
*coalesced = true;
return edata;
if (prev != NULL) {
if (edata_size_get(prev) > max_prev_neighbor) {
emap_release_edata(
tsdn, pac->emap, prev, ecache->state);
} else {
if (!extent_coalesce(tsdn, pac, ehooks, ecache,
edata, prev, false)) {
edata = prev;
if (ecache->delay_coalesce) {
/* Do minimal coalescing. */
*coalesced = true;
return edata;
}
again = true;
}
again = true;
}
}
} while (again);