]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: calculate threads number from type specific values
authorKarel Zak <kzak@redhat.com>
Thu, 16 Jul 2020 08:51:14 +0000 (10:51 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 13 Nov 2020 08:19:02 +0000 (09:19 +0100)
Don't use global CPU masks (like "online" or "present") to
calculate type specific number of threads due systems with
mixed CPU types.

It's also necessary to check all thread_siblings maps to get the
highest number, because some threads (CPUs) may be disables, for
example old lscpu calculates number of threads from the cpu0 and
if you disable cpu0's sibling (cpu4):

CPU(s):                          8
On-line CPU(s) list:             0-7
Thread(s) per core:              2        <---
Core(s) per socket:              4
Socket(s):                       1

 # chcpu --disable 4
 CPU 4 disabled

CPU(s):                          8
On-line CPU(s) list:             0-3,5-7
Off-line CPU(s) list:            4
Thread(s) per core:              1        <--- !
Core(s) per socket:              4
Socket(s):                       1

because 'thread_siblings' contains only one thread for cpu0:

 # cat /sys/devices/system/cpu/cpu{0,1,2,3,4,5,6,7}/topology/thread_siblings_list
 0
 1,5
 2,6
 3,7
 cat: /sys/devices/system/cpu/cpu4/topology/thread_siblings_list: No such file or directory
 1,5
 2,6
 3,7

Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/lscpu-cputype.c

index 86c93b5fda4a1b6267e1ce8593a370565b306acc..f12341d0c1375cba05ece31f05845d473871f0e1 100644 (file)
@@ -217,6 +217,7 @@ 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;
 
        sys = cxt->syscpu;                              /* /sys/devices/system/cpu/ */
        setsize = CPU_ALLOC_SIZE(cxt->maxcpus);         /* CPU set size */
@@ -226,7 +227,7 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
                struct lscpu_cpu *cpu = cxt->cpus[i];
                cpu_set_t *thread_siblings = NULL, *core_siblings = NULL;
                cpu_set_t *book_siblings = NULL, *drawer_siblings = NULL;
-               int num;
+               int num, n;
 
                if (cpu->type != ct)
                        continue;
@@ -248,6 +249,12 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
                ul_path_readf_cpuset(sys, &drawer_siblings, cxt->maxcpus,
                                        "cpu%d/topology/drawer_siblings", num);
 
+               n = CPU_COUNT_S(setsize, thread_siblings);
+               if (!n)
+                       n = 1;
+               if (n > nthreads)
+                       nthreads = n;
+
                /* Allocate arrays for topology maps.
                 *
                 * For each map we make sure that it can have up to ncpuspos
@@ -274,42 +281,12 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
                if (drawer_siblings)
                        add_cpuset_to_array(ct->drawermaps, &ct->ndrawers, drawer_siblings, setsize);
 
-               /* calculate threads */
-               if (!ct->nthreads) {
-                       int ndrawers, nbooks, nsockets, ncores, nthreads;
-
-                       /* threads within one core */
-                       nthreads = CPU_COUNT_S(setsize, thread_siblings);
-                       if (!nthreads)
-                               nthreads = 1;
-
-                       /* cores within one socket */
-                       ncores = CPU_COUNT_S(setsize, core_siblings) / nthreads;
-                       if (!ncores)
-                               ncores = 1;
-
-                       /* number of sockets within one book.  Because of odd /
-                        * non-present cpu maps and to keep calculation easy we make
-                        * sure that nsockets and nbooks is at least 1.
-                        */
-                       nsockets = cxt->npresents / nthreads / ncores;
-                       if (!nsockets)
-                               nsockets = 1;
-
-                       /* number of books */
-                       nbooks = cxt->npresents / nthreads / ncores / nsockets;
-                       if (!nbooks)
-                               ct->nbooks = 1;
-
-                       /* number of drawers */
-                       ndrawers = cxt->npresents / nbooks / nthreads / ncores / nsockets;
-                       if (!ndrawers)
-                               ndrawers = 1;
-
-                       ct->nthreads = ndrawers * nbooks * nsockets * ncores * nthreads;
-               }
        }
 
+       ct->nthreads =  (ct->ndrawers ?: 1) *
+                       (ct->nbooks   ?: 1) *
+                       (ct->nsockets ?: 1) *
+                       (ct->ncores   ?: 1) * nthreads;
 
        DBG(TYPE, ul_debugobj(ct, " nthreads: %d", ct->nthreads));
        DBG(TYPE, ul_debugobj(ct, "   ncores: %d", ct->ncores));