]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dpdk: replace TSC clock with GetTime (gettimeofday) function 11492/head 11511/head
authorLukas Sismis <lsismis@oisf.net>
Sun, 14 Jul 2024 09:08:49 +0000 (11:08 +0200)
committerLukas Sismis <lukas.sismis@gmail.com>
Sun, 14 Jul 2024 09:12:06 +0000 (11:12 +0200)
Getting clock through Time Stamp Counter (TSC) can be precise and fast,
however only for a short duration of time.
The implementation across CPUs seems to vary. The original idea is to
increment the counter with every tick. Then dividing the delta of CPU ticks
by the CPU frequency can return the time that passed.
However, the CPU clock/frequency can change over time, resulting in uneven
incrementation of TSC. On some CPUs this is handled by extra logic.
As a result, obtaining time through this method might drift from the real
time.

This commit therefore substitues TSC time retrieval by the standard system
call wrapped in GetTime function - on Linux it is gettimeofday.

Ticket: 7116

(cherry picked from commit 35dffc6b32edefdccff18710abdb6f7bc6a1145f)

src/runmode-dpdk.c
src/source-dpdk.c
src/source-dpdk.h

index fb49d6ed9e01c59e4bfae6b919be6cc209d36b08..e9642a9beb08ab34f0b9981f2123c87caae92e8a 100644 (file)
@@ -305,7 +305,6 @@ static void InitEal(void)
     if (retval < 0) { // retval bound to the result of rte_eal_init
         FatalError("DPDK EAL initialization error: %s", rte_strerror(-retval));
     }
-    DPDKSetTimevalOfMachineStart();
 }
 
 static void DPDKDerefConfig(void *conf)
index 6a7833ee4b623f7047a4b487e943212f4666d27e..d6d5b9c431454f820ff391f1415e47a9230e0a40 100644 (file)
@@ -91,8 +91,7 @@ TmEcode NoDPDKSupportExit(ThreadVars *tv, const void *initdata, void **data)
 #include "util-dpdk-bonding.h"
 #include <numa.h>
 
-#define BURST_SIZE 32
-static struct timeval machine_start_time = { 0, 0 };
+#define BURST_SIZE                   32
 // interrupt mode constants
 #define MIN_ZERO_POLL_COUNT          10U
 #define MIN_ZERO_POLL_COUNT_TO_SLEEP 10U
@@ -145,11 +144,7 @@ static TmEcode DecodeDPDKThreadInit(ThreadVars *, const void *, void **);
 static TmEcode DecodeDPDKThreadDeinit(ThreadVars *tv, void *data);
 static TmEcode DecodeDPDK(ThreadVars *, Packet *, void *);
 
-static uint64_t CyclesToMicroseconds(uint64_t cycles);
-static uint64_t CyclesToSeconds(uint64_t cycles);
 static void DPDKFreeMbufArray(struct rte_mbuf **mbuf_array, uint16_t mbuf_cnt, uint16_t offset);
-static uint64_t DPDKGetSeconds(void);
-
 static bool InterruptsRXEnable(uint16_t port_id, uint16_t queue_id)
 {
     uint32_t event_data = port_id << UINT16_WIDTH | queue_id;
@@ -191,57 +186,6 @@ static void DPDKFreeMbufArray(struct rte_mbuf **mbuf_array, uint16_t mbuf_cnt, u
     }
 }
 
-static uint64_t CyclesToMicroseconds(const uint64_t cycles)
-{
-    const uint64_t ticks_per_us = rte_get_tsc_hz() / 1000000;
-    if (ticks_per_us == 0) {
-        return 0;
-    }
-    return cycles / ticks_per_us;
-}
-
-static uint64_t CyclesToSeconds(const uint64_t cycles)
-{
-    const uint64_t ticks_per_s = rte_get_tsc_hz();
-    if (ticks_per_s == 0) {
-        return 0;
-    }
-    return cycles / ticks_per_s;
-}
-
-static void CyclesAddToTimeval(
-        const uint64_t cycles, struct timeval *orig_tv, struct timeval *new_tv)
-{
-    uint64_t usec = CyclesToMicroseconds(cycles) + orig_tv->tv_usec;
-    new_tv->tv_sec = orig_tv->tv_sec + usec / 1000000;
-    new_tv->tv_usec = (usec % 1000000);
-}
-
-void DPDKSetTimevalOfMachineStart(void)
-{
-    gettimeofday(&machine_start_time, NULL);
-    machine_start_time.tv_sec -= DPDKGetSeconds();
-}
-
-/**
- * Initializes real_tv to the correct real time. Adds TSC counter value to the timeval of
- * the machine start
- * @param machine_start_tv - timestamp when the machine was started
- * @param real_tv
- */
-static SCTime_t DPDKSetTimevalReal(struct timeval *machine_start_tv)
-{
-    struct timeval real_tv;
-    CyclesAddToTimeval(rte_get_tsc_cycles(), machine_start_tv, &real_tv);
-    return SCTIME_FROM_TIMEVAL(&real_tv);
-}
-
-/* get number of seconds from the reset of TSC counter (typically from the machine start) */
-static uint64_t DPDKGetSeconds(void)
-{
-    return CyclesToSeconds(rte_get_tsc_cycles());
-}
-
 static void DevicePostStartPMDSpecificActions(DPDKThreadVars *ptv, const char *driver_name)
 {
     if (strcmp(driver_name, "net_bonding") == 0) {
@@ -401,10 +345,10 @@ static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot)
     SCEnter();
     Packet *p;
     uint16_t nb_rx;
-    time_t last_dump = 0;
-    time_t current_time;
+    SCTime_t last_dump = { 0 };
+    SCTime_t current_time;
     bool segmented_mbufs_warned = 0;
-    SCTime_t t = DPDKSetTimevalReal(&machine_start_time);
+    SCTime_t t = TimeGet();
     uint64_t last_timeout_msec = SCTIME_MSECS(t);
 
     DPDKThreadVars *ptv = (DPDKThreadVars *)data;
@@ -439,7 +383,7 @@ static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot)
 
         nb_rx = rte_eth_rx_burst(ptv->port_id, ptv->queue_id, ptv->received_mbufs, BURST_SIZE);
         if (unlikely(nb_rx == 0)) {
-            t = DPDKSetTimevalReal(&machine_start_time);
+            t = TimeGet();
             uint64_t msecs = SCTIME_MSECS(t);
             if (msecs > last_timeout_msec + 100) {
                 TmThreadsCaptureHandleTimeout(tv, NULL);
@@ -480,7 +424,7 @@ static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot)
                 p->flags |= PKT_IGNORE_CHECKSUM;
             }
 
-            p->ts = DPDKSetTimevalReal(&machine_start_time);
+            p->ts = TimeGet();
             p->dpdk_v.mbuf = ptv->received_mbufs[i];
             p->ReleasePacket = DPDKReleasePacket;
             p->dpdk_v.copy_mode = ptv->copy_mode;
@@ -536,8 +480,8 @@ static TmEcode ReceiveDPDKLoop(ThreadVars *tv, void *data, void *slot)
         }
 
         /* Trigger one dump of stats every second */
-        current_time = DPDKGetSeconds();
-        if (current_time != last_dump) {
+        current_time = TimeGet();
+        if (current_time.secs != last_dump.secs) {
             DPDKDumpCounters(ptv);
             last_dump = current_time;
         }
index b962d866d4bdeb6c1f352cb37074746837804a98..edc19ec917d0d4c61cd0975dc59022a8fb54a0ca 100644 (file)
@@ -42,7 +42,6 @@ typedef enum { DPDK_COPY_MODE_NONE, DPDK_COPY_MODE_TAP, DPDK_COPY_MODE_IPS } Dpd
 // Offloads
 #define DPDK_RX_CHECKSUM_OFFLOAD (1 << 4) /**< Enable chsum offload */
 
-void DPDKSetTimevalOfMachineStart(void);
 typedef struct DPDKIfaceConfig_ {
 #ifdef HAVE_DPDK
     char iface[RTE_ETH_NAME_MAX_LEN];