From: Willy Tarreau Date: Fri, 21 Jul 2023 15:03:20 +0000 (+0200) Subject: MINOR: cpu-topo: implement a sorting mechanism for CPU index X-Git-Tag: v3.2-dev8~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18133a054d7259d54ef7f584096f1f40e8af0790;p=thirdparty%2Fhaproxy.git MINOR: cpu-topo: implement a sorting mechanism for CPU index CPU selection will be performed by sorting CPUs according to various criteria. For dumps however, that's really not convenient and we'll need to reorder the CPUs according to their index only. This is what the new function cpu_reorder_by_index() does. It's called in thread_detect_count() before dumping the CPU topology. --- diff --git a/include/haproxy/cpu_topo.h b/include/haproxy/cpu_topo.h index 72c611380..d80244079 100644 --- a/include/haproxy/cpu_topo.h +++ b/include/haproxy/cpu_topo.h @@ -43,4 +43,14 @@ int cpu_map_configured(void); */ void cpu_dump_topology(const struct ha_cpu_topo *topo); +/* re-order a CPU topology array by CPU index only, to undo the function above, + * in case other calls need to be made on top of this. + */ +void cpu_reorder_by_index(struct ha_cpu_topo *topo, int entries); + +/* Functions used by qsort to compare hardware CPUs (not meant to be used from + * outside cpu_topo). + */ +int _cmp_cpu_index(const void *a, const void *b); + #endif /* _HAPROXY_CPU_TOPO_H */ diff --git a/src/cpu_topo.c b/src/cpu_topo.c index d1431a503..363ab8707 100644 --- a/src/cpu_topo.c +++ b/src/cpu_topo.c @@ -221,6 +221,32 @@ void cpu_dump_topology(const struct ha_cpu_topo *topo) } } +/* function used by qsort to re-arrange CPUs by index only, to restore original + * ordering. + */ +int _cmp_cpu_index(const void *a, const void *b) +{ + const struct ha_cpu_topo *l = (const struct ha_cpu_topo *)a; + const struct ha_cpu_topo *r = (const struct ha_cpu_topo *)b; + + /* next, IDX, so that SMT ordering is preserved */ + if (l->idx >= 0 && l->idx < r->idx) + return -1; + if (l->idx > r->idx && r->idx >= 0) + return 1; + + /* exactly the same (e.g. absent, should not happend) */ + return 0; +} + +/* re-order a CPU topology array by CPU index only. This is mostly used before + * listing CPUs regardless of their characteristics. + */ +void cpu_reorder_by_index(struct ha_cpu_topo *topo, int entries) +{ + qsort(topo, entries, sizeof(*topo), _cmp_cpu_index); +} + /* 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. diff --git a/src/thread.c b/src/thread.c index 0227d4a16..7a720d827 100644 --- a/src/thread.c +++ b/src/thread.c @@ -1695,8 +1695,10 @@ void thread_detect_count(void) } #if defined(USE_THREAD) && defined(USE_CPU_AFFINITY) - if (global.tune.debug & GDBG_CPU_AFFINITY) + if (global.tune.debug & GDBG_CPU_AFFINITY) { + cpu_reorder_by_index(ha_cpu_topo, cpu_topo_maxcpus); cpu_dump_topology(ha_cpu_topo); + } #endif return; }