]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
hugepages: run hugepage check only on DPDK runmode and on Linux 10553/head
authorLukas Sismis <lsismis@oisf.net>
Sat, 10 Feb 2024 19:04:55 +0000 (20:04 +0100)
committerLukas Sismis <lukas.sismis@gmail.com>
Sat, 2 Mar 2024 09:36:50 +0000 (10:36 +0100)
Previous implementation allowed FreeBSD to enter into the hugepage
analysis. It then failed with an error message because hugepage/
NUMA node paths that are used in the codebase to retrieve info about
the system are not the same with the structure in Linux.

Additionally, the messages were logged on error level. It has been
demoted to info level because the whole hugepage analysis checkup is
only for informational purposes and does not affect Suricata operation.

The hugepage analysis and the hugepage snapshots are now limited to
only run in the DPDK runmode.

Ticket: #6760
Ticket: #6762
(cherry picked from commit 4b0704db5501c76592b2e12912b82a17f95fd842)

src/suricata.c
src/util-hugepages.c

index d0e104938cb404f56beb417ab17a9f8c7c6ced7c..82d18b930722ed6bfed27776faa4bf324d13019a 100644 (file)
@@ -2971,7 +2971,10 @@ int SuricataMain(int argc, char **argv)
         goto out;
     }
 
-    SystemHugepageSnapshot *prerun_snap = SystemHugepageSnapshotCreate();
+    SystemHugepageSnapshot *prerun_snap = NULL;
+    if (run_mode == RUNMODE_DPDK)
+        prerun_snap = SystemHugepageSnapshotCreate();
+
     SCSetStartTime(&suricata);
     RunModeDispatch(suricata.run_mode, suricata.runmode_custom_mode,
             suricata.capture_plugin_name, suricata.capture_plugin_args);
@@ -3029,13 +3032,12 @@ int SuricataMain(int argc, char **argv)
     OnNotifyRunning();
 
     PostRunStartedDetectSetup(&suricata);
-
-    SystemHugepageSnapshot *postrun_snap = SystemHugepageSnapshotCreate();
-    if (run_mode == RUNMODE_DPDK) // only DPDK uses hpages at the moment
+    if (run_mode == RUNMODE_DPDK) { // only DPDK uses hpages at the moment
+        SystemHugepageSnapshot *postrun_snap = SystemHugepageSnapshotCreate();
         SystemHugepageEvaluateHugepages(prerun_snap, postrun_snap);
-    SystemHugepageSnapshotDestroy(prerun_snap);
-    SystemHugepageSnapshotDestroy(postrun_snap);
-
+        SystemHugepageSnapshotDestroy(prerun_snap);
+        SystemHugepageSnapshotDestroy(postrun_snap);
+    }
     SCPledge();
     SuricataMainLoop(&suricata);
 
index 2af74c3e4c6e25e3e2d1a242c0bbd3072b39a24d..5ad3519440376235e0cbfb345ff52a5f9b79f6d4 100644 (file)
@@ -24,6 +24,7 @@
 #include "suricata.h"
 #include "util-debug.h"
 #include "util-hugepages.h"
+#include "util-path.h"
 
 static uint16_t SystemHugepageSizesCntPerNodeGet(uint16_t node_index);
 static uint16_t SystemNodeCountGet(void);
@@ -36,18 +37,28 @@ static void SystemHugepageNodeInfoDestroy(NodeInfo *n);
 static void SystemHugepageNodeInfoDump(NodeInfo *n);
 static void SystemHugepageSnapshotDump(SystemHugepageSnapshot *s);
 
+typedef enum OSHugepageAction_ {
+    OS_UNKNOWN, // unknown/unsupported OS
+    OS_LINUX_SYS_DEVICES,
+} OSHugepageAction;
+
+static OSHugepageAction SystemHugepageDetermineOS(void)
+{
+    // try Linux
+    if (SCPathExists("/sys/devices/system/node/")) {
+        return OS_LINUX_SYS_DEVICES;
+    }
+
+    return OS_UNKNOWN;
+}
+
 static bool SystemHugepageSupported(void)
 {
-#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun
-    return true;
-#else
+    if (SystemHugepageDetermineOS() != OS_UNKNOWN)
+        return true;
     return false;
-#endif /* !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun */
 }
 
-// block of all hugepage-specific internal functions
-#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun
-
 /**
  * \brief Linux-specific function to detect number of NUMA nodes on the system
  * \returns number of NUMA nodes, 0 on error
@@ -56,16 +67,14 @@ static uint16_t SystemNodeCountGetLinux(void)
 {
     char dir_path[] = "/sys/devices/system/node/";
     DIR *dir = opendir(dir_path);
-    if (dir == NULL) {
-        SCLogError("unable to open %s", dir_path);
-        return 0;
-    }
+    if (dir == NULL)
+        FatalError("unable to open %s", dir_path);
 
     uint16_t count = 0;
     struct dirent *entry;
     while ((entry = readdir(dir)) != NULL) {
         char d_name[] = "node";
-        if (entry->d_type == DT_DIR && strncmp(entry->d_name, d_name, strlen(d_name)) == 0)
+        if (SCIsRegularDirectory(entry) && strncmp(entry->d_name, d_name, strlen(d_name)) == 0)
             count++;
     }
     closedir(dir);
@@ -83,7 +92,7 @@ static uint16_t SystemHugepageSizesCntPerNodeGetLinux(uint16_t node_index)
     snprintf(dir_path, sizeof(dir_path), "/sys/devices/system/node/node%d/hugepages/", node_index);
     DIR *dir = opendir(dir_path);
     if (dir == NULL) {
-        SCLogError("unable to open %s", dir_path);
+        SCLogInfo("unable to open %s", dir_path);
         return 0;
     }
 
@@ -91,7 +100,7 @@ static uint16_t SystemHugepageSizesCntPerNodeGetLinux(uint16_t node_index)
     struct dirent *entry;
     while ((entry = readdir(dir)) != NULL) {
         char d_name[] = "hugepages-";
-        if (entry->d_type == DT_DIR && strncmp(entry->d_name, d_name, strlen(d_name)) == 0)
+        if (SCIsRegularDirectory(entry) && strncmp(entry->d_name, d_name, strlen(d_name)) == 0)
             count++;
     }
     closedir(dir);
@@ -111,14 +120,13 @@ static void SystemHugepagePerNodeGetHugepageSizesLinux(
     char dir_path[256];
     snprintf(dir_path, sizeof(dir_path), "/sys/devices/system/node/node%d/hugepages/", node_index);
     DIR *dir = opendir(dir_path);
-    if (dir == NULL) {
-        SCLogError("unable to open %s", dir_path);
-        return;
-    }
+    if (dir == NULL)
+        FatalError("unable to open %s", dir_path);
+
     uint16_t index = 0;
     struct dirent *entry;
     while ((entry = readdir(dir)) != NULL) {
-        if (entry->d_type == DT_DIR && strncmp(entry->d_name, "hugepages-", 10) == 0) {
+        if (SCIsRegularDirectory(entry) && strncmp(entry->d_name, "hugepages-", 10) == 0) {
             sscanf(entry->d_name, "hugepages-%ukB", &(hp_sizes[index]));
             index++;
         }
@@ -146,11 +154,11 @@ static int16_t SystemHugepagePerNodeGetHugepageInfoLinux(
                 node_index, hp_sizes[i]);
         FILE *f = fopen(path, "r");
         if (!f) {
-            SCLogError("unable to open %s", path);
-            return -SC_EEXIST;
+            SCLogInfo("unable to open %s", path);
+            return -SC_ENOENT;
         }
         if (fscanf(f, "%hu", &hugepages[i].allocated) != 1) {
-            SCLogError("failed to read the total number of allocated hugepages (%ukB) on node %hu",
+            SCLogInfo("failed to read the total number of allocated hugepages (%ukB) on node %hu",
                     hp_sizes[i], node_index);
             fclose(f);
             return -SC_EINVAL;
@@ -162,11 +170,11 @@ static int16_t SystemHugepagePerNodeGetHugepageInfoLinux(
                 node_index, hp_sizes[i]);
         f = fopen(path, "r");
         if (!f) {
-            SCLogError("unable to open %s", path);
-            return -SC_EEXIST;
+            SCLogInfo("unable to open %s", path);
+            return -SC_ENOENT;
         }
         if (fscanf(f, "%hu", &hugepages[i].free) != 1) {
-            SCLogError("failed to read the total number of free hugepages (%ukB) on node %hu",
+            SCLogInfo("failed to read the total number of free hugepages (%ukB) on node %hu",
                     hp_sizes[i], node_index);
             fclose(f);
             return -SC_EINVAL;
@@ -177,8 +185,6 @@ static int16_t SystemHugepagePerNodeGetHugepageInfoLinux(
     return 0;
 }
 
-#endif /* !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun */
-
 /**
  * \brief The function gathers information about hugepages on a given node
  * \param[in] node_index index of the NUMA node
@@ -189,8 +195,8 @@ static int16_t SystemHugepagePerNodeGetHugepageInfo(uint16_t node_index, NodeInf
 {
     uint16_t hp_sizes_cnt = SystemHugepageSizesCntPerNodeGet(node_index);
     if (hp_sizes_cnt == 0) {
-        SCLogError("hugepages not found for node %d", node_index);
-        return -SC_EEXIST;
+        SCLogInfo("hugepages not found for node %d", node_index);
+        return -SC_ENOENT;
     }
     uint32_t *hp_sizes = SCCalloc(hp_sizes_cnt, sizeof(*hp_sizes));
     if (hp_sizes == NULL) {
@@ -202,10 +208,9 @@ static int16_t SystemHugepagePerNodeGetHugepageInfo(uint16_t node_index, NodeInf
     node->num_hugepage_sizes = hp_sizes_cnt;
 
     int16_t ret = 0;
-#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun
-    ret = SystemHugepagePerNodeGetHugepageInfoLinux(
-            node->hugepages, hp_sizes, node->num_hugepage_sizes, node_index);
-#endif /* !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun */
+    if (SystemHugepageDetermineOS() == OS_LINUX_SYS_DEVICES)
+        ret = SystemHugepagePerNodeGetHugepageInfoLinux(
+                node->hugepages, hp_sizes, node->num_hugepage_sizes, node_index);
 
     SCFree(hp_sizes);
     return ret;
@@ -217,9 +222,8 @@ static int16_t SystemHugepagePerNodeGetHugepageInfo(uint16_t node_index, NodeInf
  */
 static uint16_t SystemNodeCountGet(void)
 {
-#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun
-    return SystemNodeCountGetLinux();
-#endif /* !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun */
+    if (SystemHugepageDetermineOS() == OS_LINUX_SYS_DEVICES)
+        return SystemNodeCountGetLinux();
     return 0;
 }
 
@@ -229,9 +233,8 @@ static uint16_t SystemNodeCountGet(void)
  */
 static uint16_t SystemHugepageSizesCntPerNodeGet(uint16_t node_index)
 {
-#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun
-    return SystemHugepageSizesCntPerNodeGetLinux(node_index);
-#endif /* !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun */
+    if (SystemHugepageDetermineOS() == OS_LINUX_SYS_DEVICES)
+        return SystemHugepageSizesCntPerNodeGetLinux(node_index);
     return 0;
 }
 
@@ -245,9 +248,8 @@ static uint16_t SystemHugepageSizesCntPerNodeGet(uint16_t node_index)
 static void SystemHugepagePerNodeGetHugepageSizes(
         uint16_t node_index, uint16_t hp_sizes_cnt, uint32_t *hp_sizes)
 {
-#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun
-    return SystemHugepagePerNodeGetHugepageSizesLinux(node_index, hp_sizes_cnt, hp_sizes);
-#endif /* !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun */
+    if (SystemHugepageDetermineOS() == OS_LINUX_SYS_DEVICES)
+        SystemHugepagePerNodeGetHugepageSizesLinux(node_index, hp_sizes_cnt, hp_sizes);
 }
 
 static HugepageInfo *SystemHugepageHugepageInfoCreate(uint16_t hp_size_cnt)
@@ -325,7 +327,7 @@ SystemHugepageSnapshot *SystemHugepageSnapshotCreate(void)
 
     uint16_t node_cnt = SystemNodeCountGet();
     if (node_cnt == 0) {
-        SCLogError("failed to obtain number of NUMA nodes in the system");
+        SCLogInfo("hugepage snapshot failed - cannot obtain number of NUMA nodes in the system");
         return NULL;
     }
     NodeInfo *nodes = SCCalloc(node_cnt, sizeof(*nodes));
@@ -386,7 +388,8 @@ void SystemHugepageEvaluateHugepages(SystemHugepageSnapshot *pre_s, SystemHugepa
                 SCLogWarning(
                         "Hugepage usage decreased while it should only increase/stay the same");
             } else if (prerun_hp->free > 0 && prerun_hp->free == postrun_hp->free) {
-                SCLogPerf("Hugepages on NUMA node %u are unused and can be deallocated", i);
+                SCLogPerf("%ukB hugepages on NUMA node %u are unused and can be deallocated",
+                        postrun_hp->size_kb, i);
             } else { // assumes this is an active NUMA node because at least some hugepages were
                      // used
                 // speculative hint only for 2048kB pages as e.g. 1 GB pages can leave a lot of room