From: Willy Tarreau Date: Wed, 12 Jul 2023 10:06:00 +0000 (+0200) Subject: MINOR: cpu-topo: update CPU topology from excluded CPUs at boot X-Git-Tag: v3.2-dev8~87 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a6fdc3eaf0f3c4c5115be3059b3c0e930ade7b05;p=thirdparty%2Fhaproxy.git MINOR: cpu-topo: update CPU topology from excluded CPUs at boot Now before trying to resolve the thread assignment to groups, we detect which CPUs are not bound at boot so that we can mark them with HA_CPU_F_EXCLUDED. This will be useful to better know on which CPUs we can count later. Note that we purposely ignore cpu-map here as we don't know how threads and groups will map to cpu-map entries, hence which CPUs will really be used. It's important to proceed this way so that when we have no info we assume they're all available. --- diff --git a/include/haproxy/cpu_topo.h b/include/haproxy/cpu_topo.h index 6a21e220e..0aa74f99e 100644 --- a/include/haproxy/cpu_topo.h +++ b/include/haproxy/cpu_topo.h @@ -9,6 +9,13 @@ extern int cpu_topo_maxcpus; extern int cpu_topo_lastcpu; extern struct ha_cpu_topo *ha_cpu_topo; +/* Detects the CPUs that will be used based on the ones the process is bound to. + * Returns non-zero on success, zero on failure. Note that it may not be + * performed in the function above because some calls may rely on other items + * being allocated (e.g. trash). + */ +int cpu_detect_usable(void); + /* Dump the CPU topology for up to cpu_topo_maxcpus CPUs for * debugging purposes. Offline CPUs are skipped. */ diff --git a/src/cpu_topo.c b/src/cpu_topo.c index 2622994d9..dd545d50f 100644 --- a/src/cpu_topo.c +++ b/src/cpu_topo.c @@ -9,6 +9,31 @@ 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; +/* 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 + * be used since we don't know upfront how individual threads will be mapped to + * groups and CPUs. + * + * Returns non-zero on success, zero on failure. Note that it may not be + * performed in the function above because some calls may rely on other items + * being allocated (e.g. trash). + */ +int cpu_detect_usable(void) +{ + struct hap_cpuset boot_set = { }; + int cpu; + + /* update the list with the CPUs currently bound to the current process */ + ha_cpuset_detect_bound(&boot_set); + + /* remove the known-excluded CPUs */ + for (cpu = 0; cpu < cpu_topo_maxcpus; cpu++) + if (!ha_cpuset_isset(&boot_set, cpu)) + ha_cpu_topo[cpu].st |= HA_CPU_F_EXCLUDED; + + return 0; +} + /* Dump the CPU topology for up to cpu_topo_maxcpus CPUs for * debugging purposes. Offline CPUs are skipped. */ diff --git a/src/haproxy.c b/src/haproxy.c index 0b36e230f..c77f88ffd 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -77,6 +77,7 @@ #include #ifdef USE_CPU_AFFINITY #include +#include #endif #include #include @@ -2049,6 +2050,12 @@ static void step_init_2(int argc, char** argv) clock_adjust_now_offset(); ready_date = date; +#ifdef USE_CPU_AFFINITY + /* we've already read the config and know what CPUs are expected + * to be used. Let's check which of these are usable. + */ + cpu_detect_usable(); +#endif /* Note: global.nbthread will be initialized as part of this call */ err_code |= check_config_validity();