]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cpu-topo: rely on _SC_NPROCESSORS_CONF to trim maxcpus
authorWilly Tarreau <w@1wt.eu>
Thu, 13 Mar 2025 09:27:22 +0000 (10:27 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 14 Mar 2025 17:30:30 +0000 (18:30 +0100)
We don't want to constantly deal with as many CPUs as a cpuset can hold,
so let's first try to trim the value to what the system claims to support
via _SC_NPROCESSORS_CONF. It is obviously still subject to the limit of
the cpuset size though. The value is stored globally so that we can
reuse it elsewhere after initialization.

include/haproxy/cpu_topo.h
src/cpu_topo.c

index 139bc81ecc2174bdfe80acb9520014dc4fa87bbd..acc04268cde31fe2d78f2edbca3bbcaf9add5c7a 100644 (file)
@@ -5,6 +5,8 @@
 #include <haproxy/cpuset.h>
 #include <haproxy/cpu_topo-t.h>
 
+extern int cpu_topo_maxcpus;
+extern int cpu_topo_lastcpu;
 extern struct ha_cpu_topo *ha_cpu_topo;
 
 #endif /* _HAPROXY_CPU_TOPO_H */
index 7d60617ae8b5baafe36a2521173009ff1cfc2324..894d8197bd086c12a906b41091179d5236e37315 100644 (file)
@@ -1,28 +1,50 @@
 #define _GNU_SOURCE
 
+#include <unistd.h>
 #include <haproxy/api.h>
 #include <haproxy/cpu_topo.h>
 
 /* CPU topology information, ha_cpuset_size() entries, allocated at boot */
+int cpu_topo_maxcpus  = -1;  // max number of CPUs supported by OS/haproxy
+int cpu_topo_lastcpu  = -1;  // last supposed online CPU (no need to look beyond)
 struct ha_cpu_topo *ha_cpu_topo = NULL;
 
+/* returns an optimal maxcpus for the current system. It will take into
+ * account what is reported by the OS, if any, otherwise will fall back
+ * to the cpuset size, which serves as an upper limit in any case.
+ */
+static int cpu_topo_get_maxcpus(void)
+{
+       int abs_max = ha_cpuset_size();
+
+#if defined(_SC_NPROCESSORS_CONF)
+       int n = (int)sysconf(_SC_NPROCESSORS_CONF);
+
+       if (n > 0 && n <= abs_max)
+               return n;
+#endif
+       return abs_max;
+}
+
 /* Allocates everything needed to store CPU topology at boot.
  * Returns non-zero on success, zero on failure.
  */
 static int cpu_topo_alloc(void)
 {
-       int maxcpus = ha_cpuset_size();
        int cpu;
 
+       cpu_topo_maxcpus = cpu_topo_get_maxcpus();
+       cpu_topo_lastcpu = cpu_topo_maxcpus - 1;
+
        /* allocate the structures used to store CPU topology info */
-       ha_cpu_topo = (struct ha_cpu_topo*)malloc(maxcpus * sizeof(*ha_cpu_topo));
+       ha_cpu_topo = (struct ha_cpu_topo*)malloc(cpu_topo_maxcpus * sizeof(*ha_cpu_topo));
        if (!ha_cpu_topo)
                return 0;
 
        /* preset all fields to -1 except the index and the state flags which
         * are assumed to all be bound and online unless detected otherwise.
         */
-       for (cpu = 0; cpu < maxcpus; cpu++) {
+       for (cpu = 0; cpu < cpu_topo_maxcpus; cpu++) {
                memset(&ha_cpu_topo[cpu], 0xff, sizeof(*ha_cpu_topo));
                ha_cpu_topo[cpu].st  = 0;
                ha_cpu_topo[cpu].idx = cpu;