From: Karel Zak Date: Thu, 16 Jul 2020 09:32:18 +0000 (+0200) Subject: lscpu: move topology stuff to separate file X-Git-Tag: v2.37-rc1~356 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f669523ba023343b7e50342782cf17a3b638d504;p=thirdparty%2Futil-linux.git lscpu: move topology stuff to separate file Signed-off-by: Karel Zak --- diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am index c0cdda728d..0032b28777 100644 --- a/sys-utils/Makemodule.am +++ b/sys-utils/Makemodule.am @@ -402,6 +402,7 @@ dist_man_MANS += sys-utils/lscpu.1 check_PROGRAMS += test_cputype test_cputype_SOURCES = sys-utils/lscpu-cputype.c \ sys-utils/lscpu-cpu.c \ + sys-utils/lscpu-topology.c \ sys-utils/lscpu-virt.c \ sys-utils/lscpu-arm.c \ sys-utils/lscpu-api.h diff --git a/sys-utils/lscpu-api.h b/sys-utils/lscpu-api.h index e09ba65fd8..2cfff7e349 100644 --- a/sys-utils/lscpu-api.h +++ b/sys-utils/lscpu-api.h @@ -190,8 +190,10 @@ int lscpu_read_cpulists(struct lscpu_cxt *cxt); int lscpu_read_archext(struct lscpu_cxt *cxt); int lscpu_read_vulnerabilities(struct lscpu_cxt *cxt); int lscpu_read_numas(struct lscpu_cxt *cxt); + int lscpu_read_topology(struct lscpu_cxt *cxt); -int lscpu_read_topolgy_ids(struct lscpu_cxt *cxt); +int lscpu_read_topology_ids(struct lscpu_cxt *cxt); +void lscpu_cputype_free_topology(struct lscpu_cputype *ct); struct lscpu_arch *lscpu_read_architecture(struct lscpu_cxt *cxt); void lscpu_free_architecture(struct lscpu_arch *ar); diff --git a/sys-utils/lscpu-cpu.c b/sys-utils/lscpu-cpu.c index 01efaafdeb..282fe8229d 100644 --- a/sys-utils/lscpu-cpu.c +++ b/sys-utils/lscpu-cpu.c @@ -76,31 +76,3 @@ int lscpu_cpus_apply_type(struct lscpu_cxt *cxt, struct lscpu_cputype *type) } return 0; } - - -int lscpu_read_topolgy_ids(struct lscpu_cxt *cxt) -{ - struct path_cxt *sys = cxt->syscpu; - size_t i; - - - for (i = 0; i < cxt->ncpus; i++) { - struct lscpu_cpu *cpu = cxt->cpus[i]; - int num = cpu->logical_id; - - DBG(TYPE, ul_debugobj(cpu, "#%d reading IDs", num)); - - if (ul_path_readf_s32(sys, &cpu->coreid, "cpu%d/topology/core_id", num) != 0) - cpu->coreid = -1; - if (ul_path_readf_s32(sys, &cpu->socketid, "cpu%d/topology/physical_package_id", num) != 0) - cpu->socketid = -1; - if (ul_path_readf_s32(sys, &cpu->bookid, "cpu%d/topology/book_id", num) != 0) - cpu->bookid = -1; - if (ul_path_readf_s32(sys, &cpu->drawerid, "cpu%d/topology/drawer_id", num) != 0) - cpu->drawerid = -1; - } - - return 0; -} - - diff --git a/sys-utils/lscpu-cputype.c b/sys-utils/lscpu-cputype.c index 389bd1b862..66cc904540 100644 --- a/sys-utils/lscpu-cputype.c +++ b/sys-utils/lscpu-cputype.c @@ -71,38 +71,6 @@ int lookup(char *line, char *pattern, char **value) return 1; } -/* add @set to the @ary, unnecessary set is deallocated. */ -static int add_cpuset_to_array(cpu_set_t **ary, int *items, cpu_set_t *set, size_t setsize) -{ - int i; - - if (!ary) - return -EINVAL; - - for (i = 0; i < *items; i++) { - if (CPU_EQUAL_S(setsize, set, ary[i])) - break; - } - if (i == *items) { - ary[*items] = set; - ++*items; - return 0; - } - CPU_FREE(set); - return 1; -} - -static void free_cpuset_array(cpu_set_t **ary, int items) -{ - int i; - - if (!ary) - return; - for (i = 0; i < items; i++) - free(ary[i]); - free(ary); -} - struct lscpu_cputype *lscpu_new_cputype(void) { struct lscpu_cputype *ct; @@ -127,6 +95,7 @@ void lscpu_unref_cputype(struct lscpu_cputype *ct) if (--ct->refcount <= 0) { DBG(TYPE, ul_debugobj(ct, " freeing")); + lscpu_cputype_free_topology(ct); free(ct->vendor); free(ct->machinetype); /* s390 */ free(ct->family); @@ -138,10 +107,6 @@ void lscpu_unref_cputype(struct lscpu_cputype *ct) free(ct->flags); free(ct->mtid); /* maximum thread id (s390) */ free(ct->addrsz); /* address sizes */ - free_cpuset_array(ct->coremaps, ct->ncores); - free_cpuset_array(ct->socketmaps, ct->nsockets); - free_cpuset_array(ct->bookmaps, ct->nbooks); - free_cpuset_array(ct->drawermaps, ct->ndrawers); free(ct); } } @@ -212,106 +177,6 @@ static void lscpu_merge_cputype(struct lscpu_cputype *a, struct lscpu_cputype *b a->addrsz = xstrdup(b->addrsz); } -/* Read topology for specified type */ -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 */ - npos = cxt->ncpuspos; /* possible CPUs */ - - DBG(TYPE, ul_debugobj(ct, "reading %s/%s/%s topology", - ct->vendor ?: "", ct->model ?: "", ct->modelname ?:"")); - - for (i = 0; i < cxt->ncpus; i++) { - 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, n; - - if (cpu->type != ct) - continue; - - num = cpu->logical_id; - if (ul_path_accessf(sys, F_OK, - "cpu%d/topology/thread_siblings", num) != 0) - continue; - - /*DBG(TYPE, ul_debugobj(ct, " #%d", num));*/ - - /* read topology maps */ - ul_path_readf_cpuset(sys, &thread_siblings, cxt->maxcpus, - "cpu%d/topology/thread_siblings", num); - ul_path_readf_cpuset(sys, &core_siblings, cxt->maxcpus, - "cpu%d/topology/core_siblings", num); - ul_path_readf_cpuset(sys, &book_siblings, cxt->maxcpus, - "cpu%d/topology/book_siblings", num); - 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 - * entries. This is because we cannot reliably calculate the - * number of cores, sockets and books on all architectures. - * E.g. completely virtualized architectures like s390 may - * have multiple sockets of different sizes. - */ - if (!ct->coremaps) - ct->coremaps = xcalloc(npos, sizeof(cpu_set_t *)); - if (!ct->socketmaps) - ct->socketmaps = xcalloc(npos, sizeof(cpu_set_t *)); - if (!ct->bookmaps && book_siblings) - ct->bookmaps = xcalloc(npos, sizeof(cpu_set_t *)); - if (!ct->drawermaps && drawer_siblings) - ct->drawermaps = xcalloc(npos, sizeof(cpu_set_t *)); - - /* add to topology maps */ - add_cpuset_to_array(ct->coremaps, &ct->ncores, thread_siblings, setsize); - add_cpuset_to_array(ct->socketmaps, &ct->nsockets, core_siblings, setsize); - - if (book_siblings) - add_cpuset_to_array(ct->bookmaps, &ct->nbooks, book_siblings, setsize); - if (drawer_siblings) - add_cpuset_to_array(ct->drawermaps, &ct->ndrawers, drawer_siblings, setsize); - - } - - 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)); - 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)); - - return 0; -} - -int lscpu_read_topology(struct lscpu_cxt *cxt) -{ - size_t i; - int rc = 0; - - for (i = 0; i < cxt->ncputypes; i++) - rc += cputype_read_topology(cxt, cxt->cputypes[i]); - - return rc; -} - - /* Describes /proc/cpuinfo fields */ struct cpuinfo_pattern { int id; /* field ID */ @@ -949,7 +814,7 @@ int main(int argc, char **argv) lscpu_read_vulnerabilities(cxt); lscpu_read_numas(cxt); lscpu_read_topology(cxt); - lscpu_read_topolgy_ids(cxt); + lscpu_read_topology_ids(cxt); lscpu_decode_arm(cxt); diff --git a/sys-utils/lscpu-topology.c b/sys-utils/lscpu-topology.c new file mode 100644 index 0000000000..6094b96c1d --- /dev/null +++ b/sys-utils/lscpu-topology.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lscpu-api.h" + +/* add @set to the @ary, unnecessary set is deallocated. */ +static int add_cpuset_to_array(cpu_set_t **ary, int *items, cpu_set_t *set, size_t setsize) +{ + int i; + + if (!ary) + return -EINVAL; + + for (i = 0; i < *items; i++) { + if (CPU_EQUAL_S(setsize, set, ary[i])) + break; + } + if (i == *items) { + ary[*items] = set; + ++*items; + return 0; + } + CPU_FREE(set); + return 1; +} + +static void free_cpuset_array(cpu_set_t **ary, int items) +{ + int i; + + if (!ary) + return; + for (i = 0; i < items; i++) + free(ary[i]); + free(ary); +} + +void lscpu_cputype_free_topology(struct lscpu_cputype *ct) +{ + if (!ct) + return; + free_cpuset_array(ct->coremaps, ct->ncores); + free_cpuset_array(ct->socketmaps, ct->nsockets); + free_cpuset_array(ct->bookmaps, ct->nbooks); + free_cpuset_array(ct->drawermaps, ct->ndrawers); +} + + +/* Read topology for specified type */ +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 */ + npos = cxt->ncpuspos; /* possible CPUs */ + + DBG(TYPE, ul_debugobj(ct, "reading %s/%s/%s topology", + ct->vendor ?: "", ct->model ?: "", ct->modelname ?:"")); + + for (i = 0; i < cxt->ncpus; i++) { + 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, n; + + if (cpu->type != ct) + continue; + + num = cpu->logical_id; + if (ul_path_accessf(sys, F_OK, + "cpu%d/topology/thread_siblings", num) != 0) + continue; + + /*DBG(TYPE, ul_debugobj(ct, " #%d", num));*/ + + /* read topology maps */ + ul_path_readf_cpuset(sys, &thread_siblings, cxt->maxcpus, + "cpu%d/topology/thread_siblings", num); + ul_path_readf_cpuset(sys, &core_siblings, cxt->maxcpus, + "cpu%d/topology/core_siblings", num); + ul_path_readf_cpuset(sys, &book_siblings, cxt->maxcpus, + "cpu%d/topology/book_siblings", num); + 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 + * entries. This is because we cannot reliably calculate the + * number of cores, sockets and books on all architectures. + * E.g. completely virtualized architectures like s390 may + * have multiple sockets of different sizes. + */ + if (!ct->coremaps) + ct->coremaps = xcalloc(npos, sizeof(cpu_set_t *)); + if (!ct->socketmaps) + ct->socketmaps = xcalloc(npos, sizeof(cpu_set_t *)); + if (!ct->bookmaps && book_siblings) + ct->bookmaps = xcalloc(npos, sizeof(cpu_set_t *)); + if (!ct->drawermaps && drawer_siblings) + ct->drawermaps = xcalloc(npos, sizeof(cpu_set_t *)); + + /* add to topology maps */ + add_cpuset_to_array(ct->coremaps, &ct->ncores, thread_siblings, setsize); + add_cpuset_to_array(ct->socketmaps, &ct->nsockets, core_siblings, setsize); + + if (book_siblings) + add_cpuset_to_array(ct->bookmaps, &ct->nbooks, book_siblings, setsize); + if (drawer_siblings) + add_cpuset_to_array(ct->drawermaps, &ct->ndrawers, drawer_siblings, setsize); + + } + + 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)); + 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)); + + return 0; +} + +int lscpu_read_topology(struct lscpu_cxt *cxt) +{ + size_t i; + int rc = 0; + + for (i = 0; i < cxt->ncputypes; i++) + rc += cputype_read_topology(cxt, cxt->cputypes[i]); + + return rc; +} + +int lscpu_read_topology_ids(struct lscpu_cxt *cxt) +{ + struct path_cxt *sys = cxt->syscpu; + size_t i; + + + for (i = 0; i < cxt->ncpus; i++) { + struct lscpu_cpu *cpu = cxt->cpus[i]; + int num = cpu->logical_id; + + DBG(TYPE, ul_debugobj(cpu, "#%d reading IDs", num)); + + if (ul_path_readf_s32(sys, &cpu->coreid, "cpu%d/topology/core_id", num) != 0) + cpu->coreid = -1; + if (ul_path_readf_s32(sys, &cpu->socketid, "cpu%d/topology/physical_package_id", num) != 0) + cpu->socketid = -1; + if (ul_path_readf_s32(sys, &cpu->bookid, "cpu%d/topology/book_id", num) != 0) + cpu->bookid = -1; + if (ul_path_readf_s32(sys, &cpu->drawerid, "cpu%d/topology/drawer_id", num) != 0) + cpu->drawerid = -1; + } + + return 0; +}