From 8c524c7c9d3607cac01ee182fd374fb465417249 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 22 Jan 2025 17:17:59 +0100 Subject: [PATCH] REORG: cpu-topo: move bound cpu detection from cpuset to cpu-topo The cpuset files are normally used only for cpu manipulations. It happens that the initial CPU binding detection was initially placed there since there was no better place, but in practice, being OS-specific, it should really be in cpu-topo. This simplifies cpuset which doesn't need to know about the OS anymore. --- include/haproxy/cpu_topo.h | 12 ++++++- include/haproxy/cpuset.h | 10 ------ src/cfgparse.c | 1 + src/cpu_topo.c | 49 +++++++++++++++++++++++++++++ src/cpuset.c | 64 -------------------------------------- src/thread.c | 1 + 6 files changed, 62 insertions(+), 75 deletions(-) diff --git a/include/haproxy/cpu_topo.h b/include/haproxy/cpu_topo.h index 0aa74f99e..bf7d98f71 100644 --- a/include/haproxy/cpu_topo.h +++ b/include/haproxy/cpu_topo.h @@ -2,7 +2,7 @@ #define _HAPROXY_CPU_TOPO_H #include -#include +#include #include extern int cpu_topo_maxcpus; @@ -16,6 +16,16 @@ extern struct ha_cpu_topo *ha_cpu_topo; */ int cpu_detect_usable(void); +/* Detects CPUs that are bound to the current process. Returns the number of + * CPUs detected or 0 if the detection failed. + */ +int ha_cpuset_detect_bound(struct hap_cpuset *set); + +/* Returns true if at least one cpu-map directive was configured, otherwise + * false. + */ +int cpu_map_configured(void); + /* Dump the CPU topology for up to cpu_topo_maxcpus CPUs for * debugging purposes. Offline CPUs are skipped. */ diff --git a/include/haproxy/cpuset.h b/include/haproxy/cpuset.h index 87c4ece82..842f09f0d 100644 --- a/include/haproxy/cpuset.h +++ b/include/haproxy/cpuset.h @@ -48,11 +48,6 @@ void ha_cpuset_assign(struct hap_cpuset *dst, struct hap_cpuset *src); */ int ha_cpuset_size(void); -/* Detects CPUs that are bound to the current process. Returns the number of - * CPUs detected or 0 if the detection failed. - */ -int ha_cpuset_detect_bound(struct hap_cpuset *set); - /* Parse cpu sets. Each CPU set is either a unique number between 0 and * ha_cpuset_size() - 1 or a range with two such numbers delimited by a dash * ('-'). Each CPU set can be a list of unique numbers or ranges separated by @@ -68,9 +63,4 @@ int parse_cpu_set(const char **args, struct hap_cpuset *cpu_set, char **err); */ void parse_cpumap(char *cpumap_str, struct hap_cpuset *cpu_set); -/* Returns true if at least one cpu-map directive was configured, otherwise - * false. - */ -int cpu_map_configured(void); - #endif /* _HAPROXY_CPUSET_H */ diff --git a/src/cfgparse.c b/src/cfgparse.c index a498f69cd..9f93f6c34 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -51,6 +51,7 @@ #include #ifdef USE_CPU_AFFINITY #include +#include #endif #include #include diff --git a/src/cpu_topo.c b/src/cpu_topo.c index dd545d50f..1f3495683 100644 --- a/src/cpu_topo.c +++ b/src/cpu_topo.c @@ -1,13 +1,18 @@ #define _GNU_SOURCE +#include +#include #include + #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; +struct cpu_map *cpu_map; /* Detects the CPUs that will be used based on the ones the process is bound to * at boot. The principle is the following: all CPUs from the boot cpuset will @@ -34,6 +39,45 @@ int cpu_detect_usable(void) return 0; } +/* Detects CPUs that are bound to the current process. Returns the number of + * CPUs detected or 0 if the detection failed. + */ +int ha_cpuset_detect_bound(struct hap_cpuset *set) +{ + ha_cpuset_zero(set); + + /* detect bound CPUs depending on the OS's API */ + if (0 +#if defined(__linux__) + || sched_getaffinity(0, sizeof(set->cpuset), &set->cpuset) != 0 +#elif defined(__FreeBSD__) + || cpuset_getaffinity(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(set->cpuset), &set->cpuset) != 0 +#else + || 1 // unhandled platform +#endif + ) { + /* detection failed */ + return 0; + } + + return ha_cpuset_count(set); +} + +/* Returns true if at least one cpu-map directive was configured, otherwise + * false. + */ +int cpu_map_configured(void) +{ + int grp, thr; + + for (grp = 0; grp < MAX_TGROUPS; grp++) { + for (thr = 0; thr < MAX_THREADS_PER_GROUP; thr++) + if (ha_cpuset_count(&cpu_map[grp].thread[thr])) + return 1; + } + return 0; +} + /* Dump the CPU topology for up to cpu_topo_maxcpus CPUs for * debugging purposes. Offline CPUs are skipped. */ @@ -109,6 +153,10 @@ static int cpu_topo_alloc(void) cpu_topo_maxcpus = cpu_topo_get_maxcpus(); cpu_topo_lastcpu = cpu_topo_maxcpus - 1; + cpu_map = calloc(MAX_TGROUPS, sizeof(*cpu_map)); + if (!cpu_map) + return 0; + /* allocate the structures used to store CPU topology info */ ha_cpu_topo = (struct ha_cpu_topo*)malloc(cpu_topo_maxcpus * sizeof(*ha_cpu_topo)); if (!ha_cpu_topo) @@ -129,6 +177,7 @@ static int cpu_topo_alloc(void) static void cpu_topo_deinit(void) { ha_free(&ha_cpu_topo); + ha_free(&cpu_map); } INITCALL0(STG_ALLOC, cpu_topo_alloc); diff --git a/src/cpuset.c b/src/cpuset.c index 6104898ef..6b5c6d9ca 100644 --- a/src/cpuset.c +++ b/src/cpuset.c @@ -1,14 +1,10 @@ #define _GNU_SOURCE -#include -#include #include #include #include #include -struct cpu_map *cpu_map; - void ha_cpuset_zero(struct hap_cpuset *set) { #if defined(CPUSET_USE_CPUSET) || defined(CPUSET_USE_FREEBSD_CPUSET) @@ -149,30 +145,6 @@ int ha_cpuset_size() #endif } -/* Detects CPUs that are bound to the current process. Returns the number of - * CPUs detected or 0 if the detection failed. - */ -int ha_cpuset_detect_bound(struct hap_cpuset *set) -{ - ha_cpuset_zero(set); - - /* detect bound CPUs depending on the OS's API */ - if (0 -#if defined(__linux__) - || sched_getaffinity(0, sizeof(set->cpuset), &set->cpuset) != 0 -#elif defined(__FreeBSD__) - || cpuset_getaffinity(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(set->cpuset), &set->cpuset) != 0 -#else - || 1 // unhandled platform -#endif - ) { - /* detection failed */ - return 0; - } - - return ha_cpuset_count(set); -} - /* Parse cpu sets. Each CPU set is either a unique number between 0 and * ha_cpuset_size() - 1 or a range with two such numbers delimited by a dash * ('-'). Each CPU set can be a list of unique numbers or ranges separated by @@ -258,39 +230,3 @@ void parse_cpumap(char *cpumap_str, struct hap_cpuset *cpu_set) ++i; } while (comma); } - -/* Returns true if at least one cpu-map directive was configured, otherwise - * false. - */ -int cpu_map_configured(void) -{ - int grp, thr; - - for (grp = 0; grp < MAX_TGROUPS; grp++) { - for (thr = 0; thr < MAX_THREADS_PER_GROUP; thr++) - if (ha_cpuset_count(&cpu_map[grp].thread[thr])) - return 1; - } - return 0; -} - -/* Allocates everything needed to store CPU information at boot. - * Returns non-zero on success, zero on failure. - */ -static int cpuset_alloc(void) -{ - /* allocate the structures used to store CPU topology info */ - cpu_map = calloc(MAX_TGROUPS, sizeof(*cpu_map)); - if (!cpu_map) - return 0; - - return 1; -} - -static void cpuset_deinit(void) -{ - ha_free(&cpu_map); -} - -INITCALL0(STG_ALLOC, cpuset_alloc); -REGISTER_POST_DEINIT(cpuset_deinit); diff --git a/src/thread.c b/src/thread.c index 7796d5c5e..160624993 100644 --- a/src/thread.c +++ b/src/thread.c @@ -35,6 +35,7 @@ # include # endif # include +# include #endif #include