MEDIUM: cfgparse: 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).
diff --git a/include/haproxy/cpuset-t.h b/include/haproxy/cpuset-t.h
index 541fb75..b26da72 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 7b35052..77af773 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -2375,6 +2375,50 @@
return ha_cpuset_count(&node_cpu_set);
}
+#elif defined(__FreeBSD__)
+static int numa_detect_topology()
+{
+ struct hap_cpuset node_cpu_set;
+ int 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;
+ }
+
+ BUG_ON(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);
+
+ ha_diag_warning("Multi-socket cpu detected, automatically binding on active CPUs of '%d' (%u active cpu(s))\n", i, ha_cpuset_count(&node_cpu_set));
+ 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()
{