BUG/MEDIUM: pools: Always update free_list in pool_gc().

In pool_gc(), when we're not using lockless pool, always update free_list,
and read from it the next element to free. As we now unlock the pool while
we're freeing the item, another thread could have updated free_list in our
back. Not doing so could lead to segfaults when pool_gc() is called.

This should be backported to 2.1.
This commit is contained in:
Olivier Houchard 2020-03-12 19:05:39 +01:00 committed by Olivier Houchard
parent bdb00c5db9
commit 51d9339d04

View File

@ -429,15 +429,14 @@ void pool_gc(struct pool_head *pool_ctx)
return;
list_for_each_entry(entry, &pools, list) {
void *temp, *next;
void *temp;
//qfprintf(stderr, "Flushing pool %s\n", entry->name);
if (entry != pool_ctx)
HA_SPIN_LOCK(POOL_LOCK, &entry->lock);
next = entry->free_list;
while (next &&
while (entry->free_list &&
(int)(entry->allocated - entry->used) > (int)entry->minavail) {
temp = next;
next = *POOL_LINK(entry, temp);
temp = entry->free_list;
entry->free_list = *POOL_LINK(entry, temp);
entry->allocated--;
if (entry != pool_ctx)
HA_SPIN_UNLOCK(POOL_LOCK, &entry->lock);
@ -445,7 +444,6 @@ void pool_gc(struct pool_head *pool_ctx)
if (entry != pool_ctx)
HA_SPIN_LOCK(POOL_LOCK, &entry->lock);
}
entry->free_list = next;
if (entry != pool_ctx)
HA_SPIN_UNLOCK(POOL_LOCK, &entry->lock);
}