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