lscpu: calculate threads number from type specific values
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>
This commit is contained in:
parent
b8a319460d
commit
fa6a21bf63
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue