Hi
Here a little patch for proper NUMA topology detection on FreeBSD.
Thanks.
Regards.
From 1fc467bf273e66b82497f28816ee3b03c88067e2 Mon Sep 17 00:00:00 2001
From: David CARLIER
Date: Mon, 6 Dec 2021 11:00:10 +
Subject: [PATCH] MEDIUM: numa detect topology on FreeBSD.
allowing for all platforms supporting cpu affinity to have a chance
to detect the cpu topology from a given valid node (e.g.
DragonflyBSD seems to be NUMA aware from a kernel's perspective
and seems to be willing start to provide userland means to get
proper info).
---
include/haproxy/cpuset-t.h | 1 +
src/cfgparse.c | 54 --
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/include/haproxy/cpuset-t.h b/include/haproxy/cpuset-t.h
index 541fb75cd..b26da7245 100644
--- a/include/haproxy/cpuset-t.h
+++ b/include/haproxy/cpuset-t.h
@@ -9,6 +9,7 @@
#ifdef __FreeBSD__
#include
#include
+#include
#include
#endif
#endif
diff --git a/src/cfgparse.c b/src/cfgparse.c
index 06352e294..a23c2f713 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -33,6 +33,7 @@
#include
#include
#include
+#include
#include
#include
@@ -2212,7 +2213,8 @@ int readcfgfile(const char *file)
return err_code;
}
-#if defined(USE_THREAD) && defined(__linux__) && defined USE_CPU_AFFINITY
+#if defined(USE_THREAD) && defined USE_CPU_AFFINITY
+#if defined(__linux__)
/* filter directory name of the pattern node */
static int numa_filter(const struct dirent *dir)
{
@@ -2372,7 +2374,55 @@ static int numa_detect_topology()
return ha_cpuset_count(&node_cpu_set);
}
+#elif defined(__FreeBSD__)
+static int numa_detect_topology()
+{
+ struct hap_cpuset node_cpu_set;
+ size_t ndomains = 0, i;
+ size_t len = sizeof(ndomains);
+
+ if (sysctlbyname("vm.ndomains", &ndomains, &len, NULL, 0) == -1) {
+ ha_notice("Cannot assess the number of CPUs domains\n");
+ return 0;
+ }
+
+ assert(ndomains <= MAXMEMDOM);
+ ha_cpuset_zero(&node_cpu_set);
+
+ /*
+ * We retrieve the first active valid CPU domain
+ * with active cpu and binding it, we returns
+ * the number of cpu from the said domain
+ */
+ for (i = 0; i < ndomains; i ++) {
+ struct hap_cpuset dom;
+ ha_cpuset_zero(&dom);
+ if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_DOMAIN, i, sizeof(dom.cpuset), &dom.cpuset) == -1)
+ continue;
+
+ if (!ha_cpuset_count(&dom))
+ continue;
+
+ ha_cpuset_assign(&node_cpu_set, &dom);
+
+ if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(node_cpu_set.cpuset), &node_cpu_set.cpuset) == -1) {
+ ha_warning("Cannot set the cpu affinity for this multi-cpu machine\n");
+
+ /* clear the cpuset used as return value */
+ ha_cpuset_zero(&node_cpu_set);
+ }
+ break;
+ }
+
+ return ha_cpuset_count(&node_cpu_set);
+}
+#else
+static int numa_detect_topology()
+{
+ return 0;
+}
#endif /* __linux__ && USE_CPU_AFFINITY */
+#endif
/*
* Returns the error code, 0 if OK, or any combination of :
@@ -2425,7 +2475,7 @@ int check_config_validity()
#if defined(USE_THREAD)
{
int numa_cores = 0;
-#if defined(__linux__) && defined USE_CPU_AFFINITY
+#if defined(USE_CPU_AFFINITY)
if (global.numa_cpu_mapping && !thread_cpu_mask_forced())
numa_cores = numa_detect_topology();
#endif
--
2.34.1