From: Olivier Houchard Date: Sat, 1 Feb 2020 16:37:22 +0000 (+0100) Subject: BUG/MEDIUM: memory_pool: Update the seq number in pool_flush(). X-Git-Tag: v2.2-dev2~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6fa08bc7bca48e0098b555e3c433e0969f46d4c;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: memory_pool: Update the seq number in pool_flush(). In pool_flush(), we can't just set the free_list to NULL, or we may suffer the ABA problem. Instead, use a double-width CAS and update the sequence number. This should be backported to 2.1, 2.0 and 1.9. This may, or may not, be related to github issue #476. --- diff --git a/src/memory.c b/src/memory.c index a858a09834..24d709f1d4 100644 --- a/src/memory.c +++ b/src/memory.c @@ -217,15 +217,20 @@ void *pool_refill_alloc(struct pool_head *pool, unsigned int avail) */ void pool_flush(struct pool_head *pool) { + struct pool_free_list cmp, new; void **next, *temp; int removed = 0; if (!pool) return; do { - next = pool->free_list; - } while (!_HA_ATOMIC_CAS(&pool->free_list, &next, NULL)); + cmp.free_list = pool->free_list; + cmp.seq = pool->seq; + new.free_list = NULL; + new.seq = cmp.seq + 1; + } while (!_HA_ATOMIC_DWCAS(&pool->free_list, &cmp, &new)); __ha_barrier_atomic_store(); + next = cmp.free_list; while (next) { temp = next; next = *POOL_LINK(pool, temp);