pull/15352/merge
SamareshSingh 12 hours ago committed by GitHub
commit 20f1e06d57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1415,13 +1415,22 @@
AC_CHECK_FUNCS([bpf_xdp_query_id])
])
# Optional libnuma probe (used for memory affinity binding, also
# mandatory for DPDK and Napatech below). Sets HAVE_LIBNUMA and links
# -lnuma when available.
AC_CHECK_LIB(numa, numa_available, [
have_libnuma=yes
AC_DEFINE([HAVE_LIBNUMA], [1], [Define to 1 if you have libnuma.])
LIBS="${LIBS} -lnuma"
], [have_libnuma=no])
# DPDK support
enable_dpdk_bond_pmd="no"
AC_ARG_ENABLE(dpdk,
AS_HELP_STRING([--enable-dpdk], [Enable DPDK support [default=no]]),
[enable_dpdk=$enableval],[enable_dpdk=no])
AS_IF([test "x$enable_dpdk" = "xyes"], [
AC_CHECK_LIB(numa, numa_available,, [numa_found="no"])
if test "$have_libnuma" = "no"; then numa_found="no"; fi
if test "$numa_found" = "no"; then
echo
echo " ERROR! libnuma not found by pkg-config, go get it"

@ -889,6 +889,17 @@ packets to process. The detect threads running on other cores will
process more packets. This is only the case after setting the option
to 'yes'.
On NUMA systems where ``set-cpu-affinity`` is enabled you can also opt
into binding each thread's memory to its local NUMA node so per-flow,
per-thread and packet pool allocations stay on the same node as the
worker CPU::
set-memory-affinity: yes
This requires Suricata to be built with libnuma (already pulled in by
``--enable-dpdk`` and the Napatech build). On a single NUMA node system
the option has no effect.
*Example 7 Balancing workload*
.. image:: suricata-yaml/balancing_workload.png

@ -59,6 +59,7 @@
int debuglog_enabled = 0;
bool threading_set_cpu_affinity = false;
bool threading_set_memory_affinity = false;
uint64_t threading_set_stack_size = 0;
/* Runmode Global Thread Names */
@ -968,6 +969,25 @@ void RunModeInitializeThreadSettings(void)
if (threading_set_cpu_affinity) {
AffinitySetupLoadFromConfig();
}
int memory_affinity = 0;
if ((SCConfGetBool("threading.set-memory-affinity", &memory_affinity)) == 0) {
threading_set_memory_affinity = false;
} else {
threading_set_memory_affinity = memory_affinity == 1;
}
if (threading_set_memory_affinity && !threading_set_cpu_affinity) {
SCLogWarning("threading.set-memory-affinity has no effect without "
"threading.set-cpu-affinity, ignoring");
threading_set_memory_affinity = false;
}
#ifndef HAVE_LIBNUMA
if (threading_set_memory_affinity) {
SCLogWarning("threading.set-memory-affinity requested but Suricata "
"was built without libnuma, ignoring");
threading_set_memory_affinity = false;
}
#endif
if ((SCConfGetFloat("threading.detect-thread-ratio", &threading_detect_ratio)) != 1) {
if (SCConfGetNode("threading.detect-thread-ratio") != NULL)
WarnInvalidConfEntry("threading.detect-thread-ratio", "%s", "1");

@ -104,6 +104,7 @@ void RunModeEnablesBypassManager(void);
int RunModeNeedsBypassManager(void);
extern bool threading_set_cpu_affinity;
extern bool threading_set_memory_affinity;
extern float threading_detect_ratio;
extern uint64_t threading_set_stack_size;

@ -48,6 +48,10 @@
#include "util-validate.h"
#include "source-pcap-file-helper.h"
#ifdef HAVE_LIBNUMA
#include <numa.h>
#endif
#ifdef PROFILE_LOCKING
thread_local uint64_t mutex_lock_contention;
thread_local uint64_t mutex_lock_wait_ticks;
@ -864,6 +868,33 @@ int TmThreadGetNbThreads(uint8_t type)
return thread_affinity[type].nb_threads;
}
/**
* \brief Bind subsequent allocations on this thread to the local NUMA node.
*
* Must be called after the thread's CPU affinity has been pinned. Uses
* MPOL_LOCAL (via numa_set_localalloc) so allocations prefer the node of
* the running CPU but can fall back to other nodes when local memory is
* exhausted. No-op when libnuma is not compiled in or the system has a
* single NUMA node.
*/
static void SetMemoryAffinityLocal(const char *name)
{
#ifdef HAVE_LIBNUMA
if (!threading_set_memory_affinity)
return;
if (numa_available() == -1)
return;
if (numa_max_node() < 1)
return;
numa_set_localalloc();
SCLogPerf("Setting memory affinity for thread \"%s\" to local NUMA node, "
"thread id %lu",
name, SCGetThreadIdLong());
#else
(void)name;
#endif
}
/**
* \brief Set the thread options (cpu affinitythread).
* Priority should be already set by pthread_create.
@ -877,6 +908,7 @@ TmEcode TmThreadSetupOptions(ThreadVars *tv)
"%"PRIu16", thread id %lu", tv->name, tv->cpu_affinity,
SCGetThreadIdLong());
SetCPUAffinity(tv->cpu_affinity);
SetMemoryAffinityLocal(tv->name);
}
#if !defined __CYGWIN__ && !defined OS_WIN32 && !defined __OpenBSD__ && !defined __sun
@ -923,6 +955,7 @@ TmEcode TmThreadSetupOptions(ThreadVars *tv)
"thread id %lu", tv->thread_priority,
tv->name, SCGetThreadIdLong());
}
SetMemoryAffinityLocal(tv->name);
TmThreadSetPrio(tv);
}
#endif

@ -1939,6 +1939,12 @@ spm-algo: auto
# Suricata is multi-threaded. Here the threading can be influenced.
threading:
set-cpu-affinity: no
# When set-cpu-affinity is enabled, also bind thread heap allocations
# to the local NUMA node so per-flow, per-thread and packet pool memory
# stays on the same NUMA as the worker CPU. Requires libnuma at build
# time (already present when DPDK or Napatech is enabled). Has no effect
# on single-NUMA systems.
set-memory-affinity: no
autopin: no
# Tune cpu affinity of threads. Each family of threads can be bound
# to specific CPUs.

Loading…
Cancel
Save