From 6c654e30ac6259b6cca1fa275c87b09516cfacc3 Mon Sep 17 00:00:00 2001 From: Lukas Sismis Date: Fri, 3 Jan 2025 13:08:49 +0100 Subject: [PATCH] threading: support previous threading configuration format Provide backward compatibility with the previous configuration format to allow smooth transition to the new format. The commit adds docs about the new format and the introduced changes. --- doc/userguide/capture-hardware/dpdk.rst | 12 ++--- doc/userguide/configuration/suricata-yaml.rst | 14 +++--- .../performance/high-performance-config.rst | 44 ++++++++--------- .../setting-up-ipsinline-for-linux.rst | 8 ++-- doc/userguide/upgrade.rst | 16 +++++++ src/util-affinity.c | 48 +++++++++++++++++-- 6 files changed, 99 insertions(+), 43 deletions(-) diff --git a/doc/userguide/capture-hardware/dpdk.rst b/doc/userguide/capture-hardware/dpdk.rst index 2b8d57c98e..5f6ac53afe 100644 --- a/doc/userguide/capture-hardware/dpdk.rst +++ b/doc/userguide/capture-hardware/dpdk.rst @@ -139,12 +139,12 @@ management and worker CPU set. threading: set-cpu-affinity: yes cpu-affinity: - - management-cpu-set: - cpu: [ 0 ] # include only these CPUs in affinity settings - - receive-cpu-set: - cpu: [ 0 ] # include only these CPUs in affinity settings - - worker-cpu-set: - cpu: [ 2,4,6,8 ] + management-cpu-set: + cpu: [ 0 ] # include only these CPUs in affinity settings + receive-cpu-set: + cpu: [ 0 ] # include only these CPUs in affinity settings + worker-cpu-set: + cpu: [ 2,4,6,8 ] ... Interrupt (power-saving) mode diff --git a/doc/userguide/configuration/suricata-yaml.rst b/doc/userguide/configuration/suricata-yaml.rst index a772181d28..f5c0941c1b 100644 --- a/doc/userguide/configuration/suricata-yaml.rst +++ b/doc/userguide/configuration/suricata-yaml.rst @@ -959,12 +959,14 @@ per available CPU/CPU core. :: - cpu-affinity: - - management-cpu-set: + threading: + set-cpu-affinity: yes + cpu-affinity: + management-cpu-set: cpu: [ 0 ] # include only these cpus in affinity settings - - receive-cpu-set: + receive-cpu-set: cpu: [ 0 ] # include only these cpus in affinity settings - - worker-cpu-set: + worker-cpu-set: cpu: [ "all" ] mode: "exclusive" # Use explicitly 3 threads and don't compute number by using @@ -975,7 +977,7 @@ per available CPU/CPU core. medium: [ "1-2" ] high: [ 3 ] default: "medium" - - verdict-cpu-set: + verdict-cpu-set: cpu: [ 0 ] prio: default: "high" @@ -2923,7 +2925,7 @@ The Teredo decoder can be disabled. It is enabled by default. ports: $TEREDO_PORTS # syntax: '[3544, 1234]' Using this default configuration, Teredo detection will run on UDP port -3544. If the `ports` parameter is missing, or set to `any`, all ports will be +1. If the `ports` parameter is missing, or set to `any`, all ports will be inspected for possible presence of Teredo. Recursion Level diff --git a/doc/userguide/performance/high-performance-config.rst b/doc/userguide/performance/high-performance-config.rst index 0cbe290320..38c310fe8d 100644 --- a/doc/userguide/performance/high-performance-config.rst +++ b/doc/userguide/performance/high-performance-config.rst @@ -202,18 +202,18 @@ In the cpu affinity section of suricata.yaml config: # Suricata is multi-threaded. Here the threading can be influenced. threading: cpu-affinity: - - management-cpu-set: - cpu: [ "1-10" ] # include only these CPUs in affinity settings - - receive-cpu-set: - cpu: [ "0-10" ] # include only these CPUs in affinity settings - - worker-cpu-set: - cpu: [ "18-35", "54-71" ] - mode: "exclusive" - prio: - low: [ 0 ] - medium: [ "1" ] - high: [ "18-35","54-71" ] - default: "high" + management-cpu-set: + cpu: [ "1-10" ] # include only these CPUs in affinity settings + receive-cpu-set: + cpu: [ "0-10" ] # include only these CPUs in affinity settings + worker-cpu-set: + cpu: [ "18-35", "54-71" ] + mode: "exclusive" + prio: + low: [ 0 ] + medium: [ "1" ] + high: [ "18-35","54-71" ] + default: "high" In the af-packet section of suricata.yaml config : @@ -324,16 +324,16 @@ In the cpu affinity section of suricata.yaml config : threading: set-cpu-affinity: yes cpu-affinity: - - management-cpu-set: - cpu: [ "120-127" ] # include only these cpus in affinity settings - - receive-cpu-set: - cpu: [ 0 ] # include only these cpus in affinity settings - - worker-cpu-set: - cpu: [ "8-55" ] - mode: "exclusive" - prio: - high: [ "8-55" ] - default: "high" + management-cpu-set: + cpu: [ "120-127" ] # include only these cpus in affinity settings + receive-cpu-set: + cpu: [ 0 ] # include only these cpus in affinity settings + worker-cpu-set: + cpu: [ "8-55" ] + mode: "exclusive" + prio: + high: [ "8-55" ] + default: "high" In the af-packet section of suricata.yaml config: diff --git a/doc/userguide/setting-up-ipsinline-for-linux.rst b/doc/userguide/setting-up-ipsinline-for-linux.rst index 2e5f0f2baf..68acbfcfa0 100644 --- a/doc/userguide/setting-up-ipsinline-for-linux.rst +++ b/doc/userguide/setting-up-ipsinline-for-linux.rst @@ -336,10 +336,10 @@ The following snippet shows a possible :ref:`suricata-yaml-threading` configurat threading: set-cpu-affinity: yes cpu-affinity: - - management-cpu-set: - cpu: [ 0 ] - - worker-cpu-set: - cpu: [ 2,4,6,8,10,12,14,16 ] + management-cpu-set: + cpu: [ 0 ] + worker-cpu-set: + cpu: [ 2,4,6,8,10,12,14,16 ] Netmap IPS mode ~~~~~~~~~~~~~~~ diff --git a/doc/userguide/upgrade.rst b/doc/userguide/upgrade.rst index 0c8b1be15a..4c59d6bd6f 100644 --- a/doc/userguide/upgrade.rst +++ b/doc/userguide/upgrade.rst @@ -155,6 +155,22 @@ Major changes - Spaces are accepted in HTTP1 URIs instead of in the protocol version. That is: `GET /a b HTTP/1.1` gets now URI as `/a b` and protocol as `HTTP/1.1` when it used to be URI as `/a` and protocol as `b HTTP/1.1` +- The configuration structure of ``threading.cpu-affinity`` has been changed + from a list format to a dictionary format. Additionally, member properties of + `*-cpu-set` nodes have been moved one level up. + The support for list items such as `- worker-cpu-set`, `- management-cpu-set`, + etc. is still supported. + To convert to the new configuration format follow the example below or + the description in :ref:`suricata-yaml-threading`. + + .. code-block:: diff + + threading: + cpu-affinity: + - - worker-cpu-set: + - cpu: [0, 1] + + worker-cpu-set: + + cpu: [0, 1] Removals ~~~~~~~~ diff --git a/src/util-affinity.c b/src/util-affinity.c index 66347c3bc5..0665374cdc 100644 --- a/src/util-affinity.c +++ b/src/util-affinity.c @@ -23,6 +23,7 @@ */ #include "suricata-common.h" +#include "suricata.h" #define _THREAD_AFFINITY #include "util-affinity.h" #include "conf.h" @@ -316,6 +317,40 @@ static uint16_t GetNextAvailableCPU(ThreadsAffinityType *taf) return cpu; } + +/** + * \brief Check if CPU affinity configuration node follows format used in Suricata 7 and below + * \retval true if CPU affinity uses Suricata <=7.0, false if it uses the new format (Suricata + * >=8.0) + */ +static bool AffinityConfigIsLegacy(void) +{ + static bool is_using_legacy_affinity_format = false; + if (thread_affinity_init_done == 0) { + // reset the flag + is_using_legacy_affinity_format = false; + } else { + return is_using_legacy_affinity_format; + } + + SCConfNode *root = SCConfGetNode("threading.cpu-affinity"); + if (root == NULL) { + return is_using_legacy_affinity_format; + } + + SCConfNode *affinity; + TAILQ_FOREACH (affinity, &root->head, next) { + // If a child does not contain "-cpu-set", then the conf is legacy + // Names in the legacy format (list of *-cpu-sets) contain + // list item IDs - "0" : "management-cpu-set", "1" : "worker-cpu-set" + if (strstr(affinity->name, "-cpu-set") == NULL) { + is_using_legacy_affinity_format = true; + return is_using_legacy_affinity_format; + } + } + + return is_using_legacy_affinity_format; +} #endif /* OS_WIN32 and __OpenBSD__ */ /** @@ -326,6 +361,7 @@ void AffinitySetupLoadFromConfig(void) #if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined sun if (thread_affinity_init_done == 0) { AffinitySetupInit(); + AffinityConfigIsLegacy(); thread_affinity_init_done = 1; } @@ -338,7 +374,8 @@ void AffinitySetupLoadFromConfig(void) SCConfNode *affinity; TAILQ_FOREACH(affinity, &root->head, next) { - const char *setname = GetAffinitySetName(affinity->name); + char *v = AffinityConfigIsLegacy() ? affinity->val : affinity->name; + const char *setname = GetAffinitySetName(v); if (setname == NULL) { continue; } @@ -351,16 +388,17 @@ void AffinitySetupLoadFromConfig(void) SCLogConfig("Found CPU affinity definition for \"%s\"", setname); - SetupCpuSets(taf, affinity, setname); - if (SetupAffinityPriority(taf, affinity, setname) < 0) { + SCConfNode *aff_query_node = AffinityConfigIsLegacy() ? affinity->head.tqh_first : affinity; + SetupCpuSets(taf, aff_query_node, setname); + if (SetupAffinityPriority(taf, aff_query_node, setname) < 0) { SCLogError("Failed to setup priority for CPU affinity type: %s", setname); continue; } - if (SetupAffinityMode(taf, affinity) < 0) { + if (SetupAffinityMode(taf, aff_query_node) < 0) { SCLogError("Failed to setup mode for CPU affinity type: %s", setname); continue; } - if (SetupAffinityThreads(taf, affinity) < 0) { + if (SetupAffinityThreads(taf, aff_query_node) < 0) { SCLogError("Failed to setup threads for CPU affinity type: %s", setname); continue; }