From fa72a5add8d9ebdcc4da5e05a8cd4259ede572d7 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Mon, 4 Oct 2021 16:01:47 +0200 Subject: [PATCH] flow: free spare pool more aggressively The flows exceeding the spare pools config setting would be freed per at max 100 flows a second. After a high speed test this would lead to excessive memory use for a long time. This patch updates the logic to free 10% of the excess flows per run, freeing multiple blocks of flows as needed. Bug: #4731. --- src/flow-spare-pool.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/flow-spare-pool.c b/src/flow-spare-pool.c index ff8402bb40..dc6b8292ec 100644 --- a/src/flow-spare-pool.c +++ b/src/flow-spare-pool.c @@ -173,28 +173,29 @@ void FlowSparePoolUpdate(uint32_t size) { const int64_t todo = (int64_t)flow_config.prealloc - (int64_t)size; if (todo < 0) { - /* remove one block at most at a time */ uint32_t to_remove = (uint32_t)(todo * -1) / 10; - if (to_remove < flow_spare_pool_block_size) - return; + while (to_remove) { + if (to_remove < flow_spare_pool_block_size) + return; - FlowSparePool *p = NULL; - SCMutexLock(&flow_spare_pool_m); - p = flow_spare_pool; - if (p != NULL) { - flow_spare_pool = p->next; - flow_spare_pool_flow_cnt -= p->queue.len; - } - SCMutexUnlock(&flow_spare_pool_m); + FlowSparePool *p = NULL; + SCMutexLock(&flow_spare_pool_m); + p = flow_spare_pool; + if (p != NULL) { + flow_spare_pool = p->next; + flow_spare_pool_flow_cnt -= p->queue.len; + to_remove -= p->queue.len; + } + SCMutexUnlock(&flow_spare_pool_m); - if (p != NULL) { - Flow *f; - while ((f = FlowQueuePrivateGetFromTop(&p->queue))) { - FlowFree(f); + if (p != NULL) { + Flow *f; + while ((f = FlowQueuePrivateGetFromTop(&p->queue))) { + FlowFree(f); + } + SCFree(p); } - SCFree(p); } - } else if (todo > 0) { FlowSparePool *head = NULL, *tail = NULL; -- 2.47.2