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 <devne...@gmail.com>
Date: Mon, 6 Dec 2021 11:00:10 +0000
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 <sys/_cpuset.h>
 #include <sys/cpuset.h>
+#include <sys/sysctl.h>
 #include <strings.h>
 #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 <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <assert.h>
 
 #include <haproxy/acl.h>
 #include <haproxy/action.h>
@@ -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<X> */
 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

Reply via email to