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