From b6fa08bc7bca48e0098b555e3c433e0969f46d4c Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Sat, 1 Feb 2020 17:37:22 +0100 Subject: [PATCH] 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. --- src/memory.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/memory.c b/src/memory.c index a858a0983..24d709f1d 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);