From 41b9836b11bbd653953f5c5dc5f87875e15fae8d Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 29 May 2024 07:03:24 +0200 Subject: [PATCH] threads: give threads more time to get ready In certain conditions, it can take a long time for threads to start up. For example in af-packet, setting up the socket, rings, etc has been observed to take close to half a second per thread, and since the threads go one by one in a preset order, this means the start up can take a lot of time if there are many threads. The old logic would just allow a hard coded 60s. This was not always enough when the number of threads was high. This patch makes the wait time take the number of threads into account. It adds a second of time budget to the base 60s for each thread. So as an example, if a system has 112 af-packet threads, it would wait 172 seconds (60 + 112) for the threads to get ready. Ticket: #7048. --- src/tm-threads.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/tm-threads.c b/src/tm-threads.c index e797b01004..557d994140 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -1801,10 +1801,20 @@ static TmEcode WaitOnThreadsRunningByType(const int t) { struct timeval start_ts; struct timeval cur_ts; - gettimeofday(&start_ts, NULL); + uint32_t thread_cnt = 0; /* on retries, this will init to the last thread that started up already */ ThreadVars *tv_start = tv_root[t]; + SCMutexLock(&tv_root_lock); + for (ThreadVars *tv = tv_start; tv != NULL; tv = tv->next) { + thread_cnt++; + } + SCMutexUnlock(&tv_root_lock); + + /* give threads a second each to start up, plus a margin of a minute. */ + uint32_t time_budget = 60 + thread_cnt; + + gettimeofday(&start_ts, NULL); again: SCMutexLock(&tv_root_lock); ThreadVars *tv = tv_start; @@ -1824,10 +1834,10 @@ again: /* 60 seconds provided for the thread to transition from * THV_INIT_DONE to THV_RUNNING */ gettimeofday(&cur_ts, NULL); - if ((cur_ts.tv_sec - start_ts.tv_sec) > 60) { + if (((uint32_t)cur_ts.tv_sec - (uint32_t)start_ts.tv_sec) > time_budget) { SCLogError("thread \"%s\" failed to " - "start in time: flags %04x", - tv->name, SC_ATOMIC_GET(tv->flags)); + "start in time: flags %04x. Total threads: %u. Time budget %us", + tv->name, SC_ATOMIC_GET(tv->flags), thread_cnt, time_budget); return TM_ECODE_FAILED; }