]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
af-packet: speed up thread sync during startup
authorVictor Julien <vjulien@oisf.net>
Thu, 30 May 2024 14:02:28 +0000 (16:02 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 4 Dec 2024 13:49:46 +0000 (14:49 +0100)
Threads are initialized sequentially to allow for a predictable mapping
of threads and queues. Not all parts of the start up need to be done
sequentially. The setting up of the rings can be very expensive, taking
of a couple of hundred milliseconds. The ring setup doesn't need to be
done sequentially though.

This patch releases the thread early, after bind but before the ring
setups.

Ticket: #7272.

src/source-af-packet.c

index e71a4f5f9f088645288222d95a91f98256eb3f97..e3c83da49de4de9a7187182079f3ec75bdf8d224 100644 (file)
@@ -609,8 +609,7 @@ void TmModuleDecodeAFPRegister (void)
     tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM;
 }
 
-
-static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose);
+static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose, const bool peer_update);
 
 static inline void AFPDumpCounters(AFPThreadVars *ptv)
 {
@@ -1290,7 +1289,7 @@ static int AFPTryReopen(AFPThreadVars *ptv)
     /* ref cnt 0, we can close the old socket */
     AFPCloseSocket(ptv);
 
-    int afp_activate_r = AFPCreateSocket(ptv, ptv->iface, 0);
+    int afp_activate_r = AFPCreateSocket(ptv, ptv->iface, 0, false);
     if (afp_activate_r != 0) {
         if (ptv->down_count % AFP_DOWN_COUNTER_INTERVAL == 0) {
             SCLogWarning("%s: can't reopen interface", ptv->iface);
@@ -1334,7 +1333,7 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
                 break;
             }
         }
-        r = AFPCreateSocket(ptv, ptv->iface, 1);
+        r = AFPCreateSocket(ptv, ptv->iface, 1, true);
         if (r < 0) {
             switch (-r) {
                 case AFP_FATAL_ERROR:
@@ -1345,7 +1344,6 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
                             "%s: failed to init socket for interface, retrying soon", ptv->iface);
             }
         }
-        AFPPeersListReachedInc();
     }
     if (ptv->afp_state == AFP_STATE_UP) {
         SCLogDebug("Thread %s using socket %d", tv->name, ptv->socket);
@@ -1869,7 +1867,8 @@ static int SetEbpfFilter(AFPThreadVars *ptv)
 }
 #endif
 
-static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose)
+/** \param peer_update increment peers reached */
+static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose, const bool peer_update)
 {
     int r;
     int ret = AFP_FATAL_ERROR;
@@ -1994,7 +1993,10 @@ static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose)
         }
     }
 #endif
-
+    /* bind() done, allow next thread to continue */
+    if (peer_update) {
+        AFPPeersListReachedInc();
+    }
     ret = AFPSetupRing(ptv, devname);
     if (ret != 0)
         goto socket_err;