]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
flow/manager: sleep handled by pthread_cond_t again
authorVictor Julien <victor@inliniac.net>
Tue, 9 Nov 2021 16:53:18 +0000 (17:53 +0100)
committerVictor Julien <vjulien@oisf.net>
Mon, 5 Sep 2022 09:59:45 +0000 (11:59 +0200)
Use only in live mode to allow FM to respond quickly to time
increases in offline mode.

Bug #4379.

(cherry picked from commit e6ac2e4e8a697a4c98b637a0d6c58dce8fb918aa)

src/flow-hash.c
src/flow-manager.c
src/flow-manager.h

index cf539840dc6590e6ab26976875b11de44d3a1983..8df9871c005ad914e57ebf1fc10edf8daa97df5b 100644 (file)
@@ -567,6 +567,7 @@ static Flow *FlowGetNew(ThreadVars *tv, FlowLookupStruct *fls, Packet *p)
             if (!(SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)) {
                 SC_ATOMIC_OR(flow_flags, FLOW_EMERGENCY);
                 FlowTimeoutsEmergency();
+                FlowWakeupFlowManagerThread();
             }
 
             f = FlowGetUsedFlow(tv, fls->dtv, &p->ts);
index 2a6bc635548a12e434026ddf9fdec52713adc061..d003e36076516873923cb8b8a952909945f73e4c 100644 (file)
@@ -88,6 +88,9 @@ SC_ATOMIC_DECLARE(uint32_t, flowrec_cnt);
 SC_ATOMIC_DECLARE(uint32_t, flowrec_busy);
 SC_ATOMIC_EXTERN(unsigned int, flow_flags);
 
+SCCtrlCondT flow_manager_ctrl_cond;
+SCCtrlMutex flow_manager_ctrl_mutex;
+
 void FlowTimeoutsInit(void)
 {
     SC_ATOMIC_SET(flow_timeouts, flow_timeouts_normal);
@@ -743,6 +746,7 @@ static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
         if (suricata_ctl_flags != 0)
             return TM_ECODE_OK;
     }
+    const bool time_is_live = TimeModeIsLive();
 
     SCLogDebug("FM %s/%d starting. min_timeout %us. Full hash pass in %us", th_v->name,
             ftd->instance, min_timeout, pass_in_sec);
@@ -955,7 +959,30 @@ static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
         memset(&sleep_startts, 0, sizeof(sleep_startts));
         gettimeofday(&sleep_startts, NULL);
 #endif
-        usleep(250);
+
+        if (emerg || !time_is_live) {
+            usleep(250);
+        } else {
+            struct timeval cond_tv;
+            gettimeofday(&cond_tv, NULL);
+            struct timeval add_tv;
+            add_tv.tv_sec = 0;
+            add_tv.tv_usec = 667 * 1000;
+            timeradd(&cond_tv, &add_tv, &cond_tv);
+
+            struct timespec cond_time = FROM_TIMEVAL(cond_tv);
+            SCCtrlMutexLock(&flow_manager_ctrl_mutex);
+            while (1) {
+                int rc = SCCtrlCondTimedwait(
+                        &flow_manager_ctrl_cond, &flow_manager_ctrl_mutex, &cond_time);
+                if (rc == ETIMEDOUT || rc < 0)
+                    break;
+                if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY) {
+                    break;
+                }
+            }
+            SCCtrlMutexUnlock(&flow_manager_ctrl_mutex);
+        }
 
 #ifdef FM_PROFILE
         struct timeval sleep_endts;
@@ -1006,6 +1033,9 @@ void FlowManagerThreadSpawn()
     }
     flowmgr_number = (uint32_t)setting;
 
+    SCCtrlCondInit(&flow_manager_ctrl_cond, NULL);
+    SCCtrlMutexInit(&flow_manager_ctrl_mutex, NULL);
+
     SCLogConfig("using %u flow manager threads", flowmgr_number);
     StatsRegisterGlobalCounter("flow.memuse", FlowGetMemuse);
 
index a157215d92e33d32f88998f9398bc6923d7e66e1..25ac22dc4e86a13f76b0f43f81f5598508f8a891 100644 (file)
 #ifndef __FLOW_MANAGER_H__
 #define __FLOW_MANAGER_H__
 
+/** flow manager scheduling condition */
+extern SCCtrlCondT flow_manager_ctrl_cond;
+extern SCCtrlMutex flow_manager_ctrl_mutex;
+#define FlowWakeupFlowManagerThread() SCCtrlCondSignal(&flow_manager_ctrl_cond)
+
 #define FlowTimeoutsReset() FlowTimeoutsInit()
 void FlowTimeoutsInit(void);
 void FlowTimeoutsEmergency(void);