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.
This commit is contained in:
Willy Tarreau 2025-03-13 10:27:22 +01:00
parent 656cedad42
commit 041462c4af
2 changed files with 27 additions and 3 deletions

View 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 */

View 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;