]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: init: properly detect NUMA bindings on large systems
authorWilly Tarreau <w@1wt.eu>
Thu, 9 Mar 2023 09:12:06 +0000 (10:12 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 9 Mar 2023 09:17:37 +0000 (10:17 +0100)
The NUMA detection code tries not to interfer with any taskset the user
could have specified in init scripts. For this it compares the number of
CPUs available with the number the process is bound to. However, the CPU
count is retrieved after being applied an upper bound of MAX_THREADS, so
if the machine has more than 64 CPUs, the comparison always fails and
makes haproxy think the user has already enforced a binding, and it does
not pin it anymore to a single NUMA node.

This can be verified by issuing:

  $ socat /path/to/sock - <<< "show info" | grep thread

On a dual 48-CPU machine it reports 64, implying that threads are allowed
to run on the second socket:

  Nbthread: 64

With this fix, the function properly reports 96, and the output shows 48,
indicating that a single NUMA node was used:

  Nbthread: 48

Of course nothing is changed when "no numa-cpu-mapping" is specified:

  Nbthread: 64

This can be backported to 2.4.

src/thread.c

index af27bbb603e0f07c41d49e723484464281bf107a..a00b3289f13dc93409cf7db75061f8275c778334 100644 (file)
@@ -357,7 +357,9 @@ void ha_rwlock_init(HA_RWLOCK_T *l)
        HA_RWLOCK_INIT(l);
 }
 
-/* returns the number of CPUs the current process is enabled to run on */
+/* returns the number of CPUs the current process is enabled to run on,
+ * regardless of any MAX_THREADS limitation.
+ */
 static int thread_cpus_enabled()
 {
        int ret = 1;
@@ -378,7 +380,6 @@ static int thread_cpus_enabled()
 #endif
 #endif
        ret = MAX(ret, 1);
-       ret = MIN(ret, MAX_THREADS);
        return ret;
 }
 
@@ -1076,6 +1077,7 @@ static void __thread_init(void)
        preload_libgcc_s();
 
        thread_cpus_enabled_at_boot = thread_cpus_enabled();
+       thread_cpus_enabled_at_boot = MIN(thread_cpus_enabled_at_boot, MAX_THREADS);
 
        memprintf(&ptr, "Built with multi-threading support (MAX_TGROUPS=%d, MAX_THREADS=%d, default=%d).",
                  MAX_TGROUPS, MAX_THREADS, thread_cpus_enabled_at_boot);