]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: improve topology calculation, use /proc/sysinfo
authorKarel Zak <kzak@redhat.com>
Thu, 16 Jul 2020 12:58:37 +0000 (14:58 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 13 Nov 2020 08:19:02 +0000 (09:19 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/lscpu-api.h
sys-utils/lscpu-topology.c

index 614512f4205c134783f5ad7583abb2b744491644..57b0a2396abb7ba8aa1a8779dc3c7d22e3cf22be 100644 (file)
@@ -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;
index 5701e2f5d2f55dec06fbe3b8d81f13bc2b93d77e..2bf3d59694343c4b76eb357b7c1e5c34f1615d31 100644 (file)
@@ -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;
 }