Fix an extent coalesce bug.
When coalescing, we should take both extents off the LRU list; otherwise decay can grab the existing outer extent through extents_evict.
This commit is contained in:
parent
fac706836f
commit
eb1b08daae
@ -355,6 +355,11 @@ extent_list_append(extent_list_t *list, extent_t *extent) {
|
|||||||
ql_tail_insert(list, extent, ql_link);
|
ql_tail_insert(list, extent, ql_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
extent_list_prepend(extent_list_t *list, extent_t *extent) {
|
||||||
|
ql_head_insert(list, extent, ql_link);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
extent_list_replace(extent_list_t *list, extent_t *to_remove,
|
extent_list_replace(extent_list_t *list, extent_t *to_remove,
|
||||||
extent_t *to_insert) {
|
extent_t *to_insert) {
|
||||||
|
20
src/extent.c
20
src/extent.c
@ -1458,13 +1458,12 @@ extent_coalesce(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
|
|||||||
bool growing_retained) {
|
bool growing_retained) {
|
||||||
assert(extent_can_coalesce(arena, extents, inner, outer));
|
assert(extent_can_coalesce(arena, extents, inner, outer));
|
||||||
|
|
||||||
if (forward && extents->delay_coalesce) {
|
if (extents->delay_coalesce) {
|
||||||
/*
|
/*
|
||||||
* The extent that remains after coalescing must occupy the
|
* Remove outer from the LRU list so that it won't be show up in
|
||||||
* outer extent's position in the LRU. For forward coalescing,
|
* decay through extents_evict.
|
||||||
* swap the inner extent into the LRU.
|
|
||||||
*/
|
*/
|
||||||
extent_list_replace(&extents->lru, outer, inner);
|
extent_list_remove(&extents->lru, outer);
|
||||||
}
|
}
|
||||||
extent_activate_locked(tsdn, arena, extents, outer,
|
extent_activate_locked(tsdn, arena, extents, outer,
|
||||||
extents->delay_coalesce);
|
extents->delay_coalesce);
|
||||||
@ -1474,9 +1473,16 @@ extent_coalesce(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
|
|||||||
forward ? inner : outer, forward ? outer : inner, growing_retained);
|
forward ? inner : outer, forward ? outer : inner, growing_retained);
|
||||||
malloc_mutex_lock(tsdn, &extents->mtx);
|
malloc_mutex_lock(tsdn, &extents->mtx);
|
||||||
|
|
||||||
|
if (!err && extents->delay_coalesce) {
|
||||||
|
if (forward) {
|
||||||
|
extent_list_prepend(&extents->lru, inner);
|
||||||
|
} else {
|
||||||
|
extent_list_prepend(&extents->lru, outer);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
if (forward && extents->delay_coalesce) {
|
if (extents->delay_coalesce) {
|
||||||
extent_list_replace(&extents->lru, inner, outer);
|
extent_list_prepend(&extents->lru, outer);
|
||||||
}
|
}
|
||||||
extent_deactivate_locked(tsdn, arena, extents, outer,
|
extent_deactivate_locked(tsdn, arena, extents, outer,
|
||||||
extents->delay_coalesce);
|
extents->delay_coalesce);
|
||||||
|
Loading…
Reference in New Issue
Block a user