diff --git a/src/flow-manager.c b/src/flow-manager.c index 905f57ed7d..eacf7fe3fe 100644 --- a/src/flow-manager.c +++ b/src/flow-manager.c @@ -872,7 +872,7 @@ static TmEcode FlowManager(ThreadVars *th_v, void *thread_data) const uint32_t sq_len = FlowSpareGetPoolSize(); const uint32_t spare_perc = sq_len * 100 / flow_config.prealloc; /* see if we still have enough spare flows */ - if (spare_perc < 90) { + if (spare_perc < 90 || spare_perc > 110) { FlowSparePoolUpdate(sq_len); } } diff --git a/src/flow-spare-pool.c b/src/flow-spare-pool.c index 4f72706bae..ff8402bb40 100644 --- a/src/flow-spare-pool.c +++ b/src/flow-spare-pool.c @@ -173,7 +173,28 @@ void FlowSparePoolUpdate(uint32_t size) { const int64_t todo = (int64_t)flow_config.prealloc - (int64_t)size; if (todo < 0) { - // remove + /* 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; + + 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); + + if (p != NULL) { + Flow *f; + while ((f = FlowQueuePrivateGetFromTop(&p->queue))) { + FlowFree(f); + } + SCFree(p); + } + } else if (todo > 0) { FlowSparePool *head = NULL, *tail = NULL;