From 6baa4df7ec2ddb8c07402b55202500f98432128f Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 16 Jul 2020 14:58:37 +0200 Subject: [PATCH] lscpu: improve topology calculation, use /proc/sysinfo Signed-off-by: Karel Zak --- sys-utils/lscpu-api.h | 8 ++++- sys-utils/lscpu-topology.c | 64 ++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/sys-utils/lscpu-api.h b/sys-utils/lscpu-api.h index 614512f420..57b0a2396a 100644 --- a/sys-utils/lscpu-api.h +++ b/sys-utils/lscpu-api.h @@ -56,8 +56,14 @@ struct lscpu_cputype { int physcoresperchip; /* Physical cores per chip */ int ncpus; /* how many CPUs references this type */ - int nthreads; /* calculated (probably same as ncpus) */ + int nthreads_per_core; + int ncores_per_socket; + int nsockets_per_book; + int nbooks_per_drawer; + int ndrawers_per_system; + + /* siblings maps */ int ncores; cpu_set_t **coremaps; int nsockets; diff --git a/sys-utils/lscpu-topology.c b/sys-utils/lscpu-topology.c index 5701e2f5d2..2bf3d59694 100644 --- a/sys-utils/lscpu-topology.c +++ b/sys-utils/lscpu-topology.c @@ -57,7 +57,8 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct { size_t i, setsize, npos; struct path_cxt *sys; - int nthreads = 0; + int nthreads = 0, sw_topo = 0; + FILE *fd; sys = cxt->syscpu; /* /sys/devices/system/cpu/ */ setsize = CPU_ALLOC_SIZE(cxt->maxcpus); /* CPU set size */ @@ -126,16 +127,59 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct } - ct->nthreads = (ct->ndrawers ?: 1) * - (ct->nbooks ?: 1) * - (ct->nsockets ?: 1) * - (ct->ncores ?: 1) * nthreads; + /* s390 detects its cpu topology via /proc/sysinfo, if present. + * Using simply the cpu topology masks in sysfs will not give + * usable results since everything is virtualized. E.g. + * virtual core 0 may have only 1 cpu, but virtual core 2 may + * five cpus. + * If the cpu topology is not exported (e.g. 2nd level guest) + * fall back to old calculation scheme. + */ + if ((fd = ul_path_fopen(cxt->procfs, "r", "sysinfo"))) { + int t0, t1; + char buf[BUFSIZ]; + + DBG(TYPE, ul_debugobj(ct, " reading sysinfo")); + + while (fgets(buf, sizeof(buf), fd) != NULL) { + if (sscanf(buf, "CPU Topology SW: %d %d %d %d %d %d", + &t0, &t1, + &ct->ndrawers_per_system, + &ct->nbooks_per_drawer, + &ct->nsockets_per_book, + &ct->ncores_per_socket) == 6) { + sw_topo = 1; + DBG(TYPE, ul_debugobj(ct, " using SW topology")); + break; + } + } + if (fd) + fclose(fd); + } + + if (ct->mtid) + ct->nthreads_per_core = atoi(ct->mtid) + 1; + else + ct->nthreads_per_core = nthreads; + + if (!sw_topo) { + ct->ndrawers_per_system = ct->nbooks_per_drawer = + ct->nsockets_per_book = ct->ncores_per_socket = 0; + if (!ct->ncores_per_socket) + ct->ncores_per_socket = ct->ncores / ct->nsockets; + if (!ct->nsockets_per_book && ct->nbooks) + ct->nsockets_per_book = ct->nsockets / ct->nbooks; + if (!ct->nbooks_per_drawer && ct->ndrawers) + ct->nbooks_per_drawer = ct->nbooks / ct->ndrawers; + if (ct->ndrawers_per_system) + ct->ndrawers_per_system = ct->ndrawers; + } - DBG(TYPE, ul_debugobj(ct, " nthreads: %d (per core: %d)", ct->nthreads, nthreads)); - DBG(TYPE, ul_debugobj(ct, " ncores: %d", ct->ncores)); - DBG(TYPE, ul_debugobj(ct, " nsockets: %d", ct->nsockets)); - DBG(TYPE, ul_debugobj(ct, " nbooks: %d", ct->nbooks)); - DBG(TYPE, ul_debugobj(ct, " ndrawers: %d", ct->ndrawers)); + DBG(TYPE, ul_debugobj(ct, " nthreads: %d (per core)", ct->nthreads_per_core)); + DBG(TYPE, ul_debugobj(ct, " ncores: %d (%d per socket)", ct->ncores, ct->ncores_per_socket)); + DBG(TYPE, ul_debugobj(ct, " nsockets: %d (%d per books)", ct->nsockets, ct->nsockets_per_book)); + DBG(TYPE, ul_debugobj(ct, " nbooks: %d (%d per drawer)", ct->nbooks, ct->nbooks_per_drawer)); + DBG(TYPE, ul_debugobj(ct, " ndrawers: %d (%d per system)", ct->ndrawers, ct->ndrawers_per_system)); return 0; } -- 2.47.3