From: Victor Julien Date: Mon, 4 Oct 2021 14:01:47 +0000 (+0200) Subject: flow: free spare pool more aggressively X-Git-Tag: suricata-7.0.0-beta1~1305 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F6438%2Fhead;p=thirdparty%2Fsuricata.git 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. --- 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;