]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cpu-topo: update CPU topology from excluded CPUs at boot
authorWilly Tarreau <w@1wt.eu>
Wed, 12 Jul 2023 10:06:00 +0000 (12:06 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 14 Mar 2025 17:30:30 +0000 (18:30 +0100)
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.

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

index 6a21e220e580439fc11919867ec289b17d8097ee..0aa74f99e04b83e60676052fb4f45a9b111896e5 100644 (file)
@@ -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 <topo> for up to cpu_topo_maxcpus CPUs for
  * debugging purposes. Offline CPUs are skipped.
  */
index 2622994d93a3f0933a34c93669afb10c6b3bfc90..dd545d50f8a7486f97ddddda4e029e1455b20880 100644 (file)
@@ -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 <topo> for up to cpu_topo_maxcpus CPUs for
  * debugging purposes. Offline CPUs are skipped.
  */
index 0b36e230f4443352fd5d721e91c3751ad7d2ff03..c77f88ffdac1f56d70d0c9c1fd17880e52080291 100644 (file)
@@ -77,6 +77,7 @@
 #include <haproxy/connection.h>
 #ifdef USE_CPU_AFFINITY
 #include <haproxy/cpuset.h>
+#include <haproxy/cpu_topo.h>
 #endif
 #include <haproxy/debug.h>
 #include <haproxy/dns.h>
@@ -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();