From: Willy Tarreau Date: Thu, 13 Mar 2025 09:27:22 +0000 (+0100) Subject: MINOR: cpu-topo: rely on _SC_NPROCESSORS_CONF to trim maxcpus X-Git-Tag: v3.2-dev8~89 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=041462c4af744b27e368243bdb2632ca4551ab22;p=thirdparty%2Fhaproxy.git MINOR: cpu-topo: rely on _SC_NPROCESSORS_CONF to trim maxcpus 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. --- diff --git a/include/haproxy/cpu_topo.h b/include/haproxy/cpu_topo.h index 139bc81ec..acc04268c 100644 --- a/include/haproxy/cpu_topo.h +++ b/include/haproxy/cpu_topo.h @@ -5,6 +5,8 @@ #include #include +extern int cpu_topo_maxcpus; +extern int cpu_topo_lastcpu; extern struct ha_cpu_topo *ha_cpu_topo; #endif /* _HAPROXY_CPU_TOPO_H */ diff --git a/src/cpu_topo.c b/src/cpu_topo.c index 7d60617ae..894d8197b 100644 --- a/src/cpu_topo.c +++ b/src/cpu_topo.c @@ -1,28 +1,50 @@ #define _GNU_SOURCE +#include #include #include /* 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;