From bd7a688b8b38901037cd2f9856533a788ebdbdf7 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 29 Jan 2025 17:51:12 +0100 Subject: [PATCH] BUG/MEDIUM: chunk: make sure to flush the trash pool before resizing Late in 3.1 we've added an integrity check to make sure we didn't keep trash objects allocated before resizing the trash with commit 0bfd36e7b8 ("MINOR: chunk: add a BUG_ON upon the next init_trash_buffer()"), but it turns out that the counter that is being checked includes the number of objects left in local thread caches. As such it can trigger despite no object being allocated. This precisely happens when setting tune.memory.hot-size to a few megabytes because some temporarily used trash objects will remain in cache. In order to address this, let's first flush the pool before running the check. That was previously done by pool_destroy() but the check had to be inserted before it. So now we first flush the trash pool, then verify it's no longer used, and finally we can destroy it. This needs to be backported to 3.1. Thanks to Christian Ruppert for reporting this bug. --- src/chunk.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/chunk.c b/src/chunk.c index ab60cd1281ab..7d7b277726db 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -89,6 +89,13 @@ static void free_trash_buffers_per_thread() /* Initialize the trash buffers. It returns 0 if an error occurred. */ int init_trash_buffers(int first) { + /* first, make sure we don't keep any trash in object in pools nor cache */ + if (pool_head_trash) { + if (!(pool_debugging & POOL_DBG_NO_CACHE)) + pool_evict_from_local_cache(pool_head_trash, 1); + pool_flush(pool_head_trash); + } + BUG_ON(!first && pool_used(pool_head_trash) > 0); /* we tried to keep a trash buffer after reinit the pool */ pool_destroy(pool_head_trash); pool_head_trash = create_pool("trash",