int cpu_topo_lastcpu = -1; // last supposed online CPU (no need to look beyond)
struct ha_cpu_topo *ha_cpu_topo = NULL;
+/* Dump the CPU topology <topo> for up to cpu_topo_maxcpus CPUs for
+ * debugging purposes. Offline CPUs are skipped.
+ */
+void cpu_dump_topology(const struct ha_cpu_topo *topo)
+{
+ int has_smt = 0;
+ int cpu, lvl;
+
+ for (cpu = 0; cpu <= cpu_topo_lastcpu; cpu++)
+ if (ha_cpu_topo[cpu].th_cnt > 1)
+ has_smt = 1;
+
+ for (cpu = 0; cpu <= cpu_topo_lastcpu; cpu++) {
+ if (ha_cpu_topo[cpu].st & HA_CPU_F_OFFLINE)
+ continue;
+
+ printf("%3d: cpu=%3d excl=%d pk=%02d no=%02d cl=%03d(%03d)",
+ cpu, ha_cpu_topo[cpu].idx,
+ (ha_cpu_topo[cpu].st & HA_CPU_F_EXCL_MASK),
+ ha_cpu_topo[cpu].pk_id,
+ ha_cpu_topo[cpu].no_id,
+ ha_cpu_topo[cpu].cl_gid,
+ ha_cpu_topo[cpu].cl_lid);
+
+ /* list only relevant cache levels */
+ for (lvl = 4; lvl >= 0; lvl--) {
+ if (ha_cpu_topo[cpu].ca_id[lvl] < 0)
+ continue;
+ printf(lvl < 3 ? " l%d=%02d" : " l%d=%03d", lvl, ha_cpu_topo[cpu].ca_id[lvl]);
+ }
+
+ printf(" ts=%03d capa=%d",
+ ha_cpu_topo[cpu].ts_id,
+ ha_cpu_topo[cpu].capa);
+
+ if (has_smt) {
+ if (ha_cpu_topo[cpu].th_cnt > 1)
+ printf(" smt=%d/%d",
+ ha_cpu_topo[cpu].th_id,
+ ha_cpu_topo[cpu].th_cnt);
+ else
+ printf(" smt=%d",
+ ha_cpu_topo[cpu].th_cnt);
+ }
+ putchar('\n');
+ }
+}
+
/* 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.