diff options
| author | Karel Zak <kzak@redhat.com> | 2020-05-13 13:33:36 +0200 |
|---|---|---|
| committer | Karel Zak <kzak@redhat.com> | 2020-11-13 09:19:02 +0100 |
| commit | 154ee5a992b1a3b1dda25c1bd7ed296197e65bfd (patch) | |
| tree | 4f460b22d4986874596c6f6c2f945ca6cf91aaf4 | |
| parent | 617d8fbec5a7075f3027108f368813a1eb231a1c (diff) | |
| download | util-linux-154ee5a992b1a3b1dda25c1bd7ed296197e65bfd.tar.gz | |
lscpu: add lscpu_read_numas()
Signed-off-by: Karel Zak <kzak@redhat.com>
| -rw-r--r-- | sys-utils/lscpu-api.h | 7 | ||||
| -rw-r--r-- | sys-utils/lscpu-cputype.c | 75 |
2 files changed, 81 insertions, 1 deletions
diff --git a/sys-utils/lscpu-api.h b/sys-utils/lscpu-api.h index aa686aa14a..6ea2df2e90 100644 --- a/sys-utils/lscpu-api.h +++ b/sys-utils/lscpu-api.h @@ -124,7 +124,11 @@ struct lscpu_cxt { struct lscpu_vulnerability *vuls; /* array of CPU vulnerabilities */ size_t nvuls; /* number of CPU vulnerabilities */ - unsigned int noalive; + size_t nnodes; /* number of NUMA modes */ + int *idx2nodenum; /* Support for discontinuous nodes */ + cpu_set_t **nodemaps; /* array with NUMA nodes */ + + unsigned int noalive : 1; }; struct lscpu_cputype *lscpu_new_cputype(void); @@ -138,6 +142,7 @@ int lscpu_read_architecture(struct lscpu_cxt *cxt); int lscpu_read_cpulists(struct lscpu_cxt *cxt); int lscpu_read_extra(struct lscpu_cxt *cxt); int lscpu_read_vulnerabilities(struct lscpu_cxt *cxt); +int lscpu_read_numas(struct lscpu_cxt *cxt); struct lscpu_cpu *lscpu_new_cpu(void); void lscpu_ref_cpu(struct lscpu_cpu *cpu); diff --git a/sys-utils/lscpu-cputype.c b/sys-utils/lscpu-cputype.c index 2540b2b227..9dcf7c741f 100644 --- a/sys-utils/lscpu-cputype.c +++ b/sys-utils/lscpu-cputype.c @@ -667,6 +667,73 @@ int lscpu_read_vulnerabilities(struct lscpu_cxt *cxt) return 0; } +static inline int is_node_dirent(struct dirent *d) +{ + return + d && +#ifdef _DIRENT_HAVE_D_TYPE + (d->d_type == DT_DIR || d->d_type == DT_UNKNOWN) && +#endif + strncmp(d->d_name, "node", 4) == 0 && + isdigit_string(d->d_name + 4); +} + +static int nodecmp(const void *ap, const void *bp) +{ + int *a = (int *) ap, *b = (int *) bp; + return *a - *b; +} + +int lscpu_read_numas(struct lscpu_cxt *cxt) +{ + size_t i = 0; + DIR *dir; + struct dirent *d; + struct path_cxt *sys; + + assert(!cxt->nnodes); + + sys = ul_new_path(_PATH_SYS_NODE); + if (!sys) + err(EXIT_FAILURE, _("failed to initialize %s handler"), _PATH_SYS_NODE); + + ul_path_set_prefix(sys, cxt->prefix); + + dir = ul_path_opendir(sys, NULL); + if (!dir) + goto done; + + while ((d = readdir(dir))) { + if (is_node_dirent(d)) + cxt->nnodes++; + } + + if (!cxt->nnodes) { + closedir(dir); + goto done; + } + + cxt->nodemaps = xcalloc(cxt->nnodes, sizeof(cpu_set_t *)); + cxt->idx2nodenum = xmalloc(cxt->nnodes * sizeof(int)); + + rewinddir(dir); + for (i = 0; (d = readdir(dir)) && i < cxt->nnodes; i++) { + if (is_node_dirent(d)) + cxt->idx2nodenum[i] = strtol_or_err(((d->d_name) + 4), + _("Failed to extract the node number")); + } + closedir(dir); + qsort(cxt->idx2nodenum, cxt->nnodes, sizeof(int), nodecmp); + + /* information about how nodes share different CPUs */ + for (i = 0; i < cxt->nnodes; i++) + ul_path_readf_cpuset(sys, &cxt->nodemaps[i], cxt->maxcpus, + "node%d/cpumap", cxt->idx2nodenum[i]); +done: + ul_unref_path(sys); + return 0; +} + #ifdef TEST_PROGRAM_CPUTYPE /* TODO: move to lscpu.c */ struct lscpu_cxt *lscpu_new_context(void) @@ -709,6 +776,13 @@ void lscpu_free_context(struct lscpu_cxt *cxt) free(cxt->vuls[i].text); } free(cxt->vuls); + + for (i = 0; i < cxt->nnodes; i++) + free(cxt->nodemaps[i]); + + free(cxt->nodemaps); + free(cxt->idx2nodenum); + free(cxt); } @@ -731,6 +805,7 @@ int main(int argc, char **argv) lscpu_read_cpulists(cxt); lscpu_read_extra(cxt); lscpu_read_vulnerabilities(cxt); + lscpu_read_numas(cxt); lscpu_free_context(cxt); return EXIT_SUCCESS; |
