]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: temporary commit
authorKarel Zak <kzak@redhat.com>
Fri, 17 Jul 2020 08:39:05 +0000 (10:39 +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-cpu.c
sys-utils/lscpu-cputype.c
sys-utils/lscpu-topology.c

index 57b0a2396abb7ba8aa1a8779dc3c7d22e3cf22be..494260f6f6e2a2fbb1f5ec5f3d72d3c46c174d02 100644 (file)
@@ -166,22 +166,8 @@ struct lscpu_cxt {
        size_t ncputypes;
        struct lscpu_cputype **cputypes;
 
-       /* CPUs as read from /proc/cpuinfo, it means online CPUs only */
-       size_t ncpus;
-       struct lscpu_cpu **cpus;
-
-       /*
-        * All maps are sequentially indexed (0..ncpuspos), the array index
-        * does not have match with cpuX number as presented by kernel. You
-        * have to use real_cpu_num() to get the real cpuX number.
-        *
-        * For example, the possible system CPUs are: 1,3,5, it means that
-        * ncpuspos=3, so all arrays are in range 0..3.
-        *
-        * TODO: Do we really need it if we have lscpu_cpu->logical_id?
-        */
-       size_t ncpuspos;        /* maximal possible CPUs */
-       int *idx2cpunum;        /* mapping index to CPU num */
+       size_t npossibles;      /* number of possible CPUs */
+       struct lscpu_cpu **cpus; /* possible CPUs, contains gaps (cups[n]=NULL) */
 
        size_t npresents;
        cpu_set_t *present;     /* mask with present CPUs */
@@ -225,12 +211,12 @@ void lscpu_free_architecture(struct lscpu_arch *ar);
 struct lscpu_virt *lscpu_read_virtualization(struct lscpu_cxt *cxt);
 void lscpu_free_virtualization(struct lscpu_virt *virt);
 
-struct lscpu_cpu *lscpu_new_cpu(void);
+struct lscpu_cpu *lscpu_new_cpu(int id);
 void lscpu_ref_cpu(struct lscpu_cpu *cpu);
 void lscpu_unref_cpu(struct lscpu_cpu *cpu);
-int lscpu_add_cpu(struct lscpu_cxt *cxt,
-                  struct lscpu_cpu *cpu,
-                  struct lscpu_cputype *ct);
+struct lscpu_cpu *lscpu_get_cpu(struct lscpu_cxt *cxt, int logical_id);
+int lscpu_cpu_set_type(struct lscpu_cpu *cpu, struct lscpu_cputype *type);
+int lscpu_create_cpus(struct lscpu_cxt *cxt, cpu_set_t *cpuset, size_t setsize);
 int lscpu_cpus_apply_type(struct lscpu_cxt *cxt, struct lscpu_cputype *type);
 struct lscpu_cpu *lscpu_cpus_loopup_by_type(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
 
index 282fe8229d7146a46db8decc6340693ff1d75ca4..dafc26bc38b98d8e873e41bd92cdb23fa490a088 100644 (file)
@@ -1,12 +1,12 @@
 #include "lscpu-api.h"
 
-struct lscpu_cpu *lscpu_new_cpu(void)
+struct lscpu_cpu *lscpu_new_cpu(int id)
 {
        struct lscpu_cpu *cpu;
 
        cpu = xcalloc(1, sizeof(struct lscpu_cpu));
        cpu->refcount = 1;
-       cpu->logical_id = -1;
+       cpu->logical_id = id;
 
        DBG(CPU, ul_debugobj(cpu, "alloc"));
        return cpu;
@@ -33,31 +33,40 @@ void lscpu_unref_cpu(struct lscpu_cpu *cpu)
        }
 }
 
-int lscpu_add_cpu(struct lscpu_cxt *cxt,
-                 struct lscpu_cpu *cpu,
-                 struct lscpu_cputype *ct)
+/*
+ * Create and initialize array with CPU structs according to @cpuset.
+ */
+int lscpu_create_cpus(struct lscpu_cxt *cxt, cpu_set_t *cpuset, size_t setsize)
 {
-       struct lscpu_cputype *type;
+       size_t n;
 
-       /* make sure the type exists */
-       if (ct)
-               type = lscpu_add_cputype(cxt, ct);
-       else
-               type = lscpu_cputype_get_default(cxt);
+       assert(!cxt->cpus);
 
-       cxt->cpus = xrealloc(cxt->cpus, (cxt->ncpus + 1)
-                               * sizeof(struct lscpu_cpu *));
+       cxt->npossibles = CPU_COUNT_S(setsize, cpuset);
+       cxt->cpus = xcalloc(1, cxt->npossibles * sizeof(struct lscpu_cpu *));
 
-       cxt->cpus[cxt->ncpus] = cpu;
-       cxt->ncpus++;
-       lscpu_ref_cpu(cpu);
+       for (n = 0; n < cxt->npossibles; n++) {
+               if (CPU_ISSET_S(n, setsize, cpuset))
+                       cxt->cpus[n] = lscpu_new_cpu(n);
+       }
+
+       return 0;
+}
+
+int lscpu_cpu_set_type(struct lscpu_cpu *cpu, struct lscpu_cputype *type)
+{
+       struct lscpu_cputype *old = cpu->type;
+
+       cpu->type = type;
 
        if (type) {
-               cpu->type = type;
                lscpu_ref_cputype(type);
                type->ncpus++;
        }
-
+       if (old) {
+               lscpu_unref_cputype(old);
+               old->ncpus--;
+       }
        return 0;
 }
 
@@ -65,14 +74,25 @@ int lscpu_cpus_apply_type(struct lscpu_cxt *cxt, struct lscpu_cputype *type)
 {
        size_t i;
 
-       for (i = 0; i < cxt->ncpus; i++) {
+       for (i = 0; i < cxt->npossibles; i++) {
                struct lscpu_cpu *cpu = cxt->cpus[i];
 
-               if (!cpu->type) {
-                       cpu->type = type;
-                       lscpu_ref_cputype(type);
-                       type->ncpus++;
-               }
+               if (cpu && !cpu->type)
+                       lscpu_cpu_set_type(cpu, type);
        }
        return 0;
 }
+
+struct lscpu_cpu *lscpu_get_cpu(struct lscpu_cxt *cxt, int logical_id)
+{
+       size_t i;
+
+       for (i = 0; i < cxt->npossibles; i++) {
+               struct lscpu_cpu *cpu = cxt->cpus[i];
+
+               if (cpu && cpu->logical_id == logical_id)
+                       return cpu;
+       }
+
+       return NULL;
+}
index 160b643787b076127c689a7c399c499a6f2fc858..7d2a1697ef7fbf0dd505e7e0edd4e176262e332a 100644 (file)
@@ -281,7 +281,8 @@ static int cmp_pattern(const void *a0, const void *b0)
  *
  * Note that s390-like "processor <n>:" lines are not suported here.
  */
-static int cpuinfo_parse_line( struct lscpu_cputype **ct,
+static int cpuinfo_parse_line( struct lscpu_cxt *cxt,
+                               struct lscpu_cputype **ct,
                                struct lscpu_cpu **cpu,
                                const char *str)
 {
@@ -309,6 +310,11 @@ static int cpuinfo_parse_line(     struct lscpu_cputype **ct,
 
        rtrim_whitespace((unsigned char *)buf);
 
+       /* prepare value */
+       v = skip_space(v);
+       if (!v || !*v)
+               return -EINVAL;
+
        /* search in cpu-types patterns */
        key.pattern = buf;
        pat = bsearch(&key, type_patterns,
@@ -316,19 +322,23 @@ static int cpuinfo_parse_line(    struct lscpu_cputype **ct,
                        sizeof(struct cpuinfo_pattern),
                        cmp_pattern);
        if (pat) {
-               /* CPU type */
                if (!*ct)
                        *ct = lscpu_new_cputype();
                stru = *ct;
+
+       /* search in cpu patterns */
        } else {
-               /* search in cpu patterns */
                pat = bsearch(&key, cpu_patterns,
                        ARRAY_SIZE(cpu_patterns),
                        sizeof(struct cpuinfo_pattern),
                        cmp_pattern);
+
                if (pat) {
-                       if (!*cpu)
-                               *cpu = lscpu_new_cpu();
+                       if (pat->id == PAT_PROCESSOR) {
+                               /* switch to another CPU only */
+                               *cpu = lscpu_get_cpu(cxt, atoi(v));
+                               return 0;
+                       }
                        stru = *cpu;
                }
        }
@@ -338,23 +348,10 @@ static int cpuinfo_parse_line(    struct lscpu_cputype **ct,
                return 1;
        }
 
-       /* prepare value */
-       v = skip_space(v);
-       if (!v || !*v)
-               return -EINVAL;
-
-       /* copy value to struct */
-       switch (pat->id) {
-       case PAT_PROCESSOR:
-               (*cpu)->logical_id = atoi(v);
-               break;
-       default:
-               /* set value as a string and cleanup */
-               strdup_to_offset(stru, pat->offset, v);
-               data = (char **) ((char *) stru + pat->offset);
-               rtrim_whitespace((unsigned char *) *data);
-               break;
-       }
+       /* set value as a string and cleanup */
+       strdup_to_offset(stru, pat->offset, v);
+       data = (char **) ((char *) stru + pat->offset);
+       rtrim_whitespace((unsigned char *) *data);
 
        return 0;
 }
@@ -376,7 +373,7 @@ static int is_processor_line(const char *str)
 /*
  * s390-like "processor <n>: value = xxx, value = yyy" lines parser.
  */
-static int cpuinfo_parse_processor_line(struct lscpu_cpu **cpu, const char *str)
+static int cpuinfo_parse_processor_line(struct lscpu_cxt *cxt, struct lscpu_cpu **cpu, const char *str)
 {
        const char *v;
        char *end = NULL;
@@ -391,10 +388,10 @@ static int cpuinfo_parse_processor_line(struct lscpu_cpu **cpu, const char *str)
        if (errno || !end || v == end || *end != ':')
                return -EINVAL;
 
-       if (!*cpu)
-               *cpu = lscpu_new_cpu();
+       /* switch to another CPU */
+       *cpu = lscpu_get_cpu(cxt, n);
 
-       (*cpu)->logical_id = n;
+       /* we don't parse anythign more from the line */
        return 0;
 }
 
@@ -405,6 +402,9 @@ int lscpu_read_cpuinfo(struct lscpu_cxt *cxt)
        FILE *fp;
        char buf[BUFSIZ];
 
+       assert(cxt->npossibles);        /* lscpu_create_cpus() required */
+       assert(cxt->cpus);
+
        DBG(GATHER, ul_debugobj(cxt, "reading cpuinfo"));
 
        fp = ul_path_fopen(cxt->procfs, "r", "cpuinfo");
@@ -422,7 +422,7 @@ int lscpu_read_cpuinfo(struct lscpu_cxt *cxt)
                         * Blank line separates CPUs
                         */
                        if (cpu)
-                               lscpu_add_cpu(cxt, cpu, type);
+                               lscpu_cpu_set_type(cpu, type);
                        else if (type) {
                                /* Generic non-cpu data. For some architectures
                                 * cpuinfo contains description block (at the
@@ -441,7 +441,6 @@ int lscpu_read_cpuinfo(struct lscpu_cxt *cxt)
                                        lscpu_add_cputype(cxt, type);
                        }
 
-                       lscpu_unref_cpu(cpu);
                        lscpu_unref_cputype(type);
                        cpu = NULL, type = NULL;
 
@@ -452,23 +451,19 @@ int lscpu_read_cpuinfo(struct lscpu_cxt *cxt)
 
                        if (is_processor_line(buf)) {
                                /* s390-like "processor <n>:" per line */
-                               cpuinfo_parse_processor_line(&cpu, p);
+                               cpuinfo_parse_processor_line(cxt, &cpu, p);
                                if (cpu) {
-                                       lscpu_add_cpu(cxt, cpu, type);
-                                       lscpu_unref_cpu(cpu);
+                                       lscpu_cpu_set_type(cpu, type);
                                        cpu = NULL;
                                }
                        } else
-                               cpuinfo_parse_line(&type, &cpu, p);
+                               cpuinfo_parse_line(cxt, &type, &cpu, p);
                }
        } while (1);
 
-       lscpu_unref_cpu(cpu);
        lscpu_unref_cputype(type);
        fclose(fp);
 
-       DBG(GATHER, ul_debug("cpuinfo done: CPUs: %zu, types: %zu",
-                               cxt->ncpus, cxt->ncputypes));
        return 0;
 }
 
@@ -577,16 +572,9 @@ int lscpu_read_cpulists(struct lscpu_cxt *cxt)
        maxn = cxt->maxcpus;
        setsize = CPU_ALLOC_SIZE(maxn);
 
+       /* create CPUs from possible mask */
        if (ul_path_readf_cpulist(cxt->syscpu, &cpuset, maxn, "possible") == 0) {
-               size_t num, idx;
-
-               cxt->ncpuspos = CPU_COUNT_S(setsize, cpuset);
-               cxt->idx2cpunum = xcalloc(cxt->ncpuspos, sizeof(int));
-
-               for (num = 0, idx = 0; num < maxn; num++) {
-                       if (CPU_ISSET_S(num, setsize, cpuset))
-                               cxt->idx2cpunum[idx++] = num;
-               }
+               lscpu_create_cpus(cxt, cpuset, setsize);
                cpuset_free(cpuset);
                cpuset = NULL;
        } else
@@ -822,14 +810,13 @@ void lscpu_free_context(struct lscpu_cxt *cxt)
        ul_unref_path(cxt->procfs);
 
        DBG(MISC, ul_debugobj(cxt, " freeing cpus"));
-       for (i = 0; i < cxt->ncpus; i++)
+       for (i = 0; i < cxt->npossibles; i++)
                lscpu_unref_cpu(cxt->cpus[i]);
 
        DBG(MISC, ul_debugobj(cxt, " freeing types"));
        for (i = 0; i < cxt->ncputypes; i++)
                lscpu_unref_cputype(cxt->cputypes[i]);
 
-       free(cxt->idx2cpunum);
        free(cxt->present);
        free(cxt->online);
        free(cxt->cputypes);
@@ -865,12 +852,13 @@ int main(int argc, char **argv)
        }
 
        lscpu_init_debug();
+
        context_init_paths(cxt);
 
+       lscpu_read_cpulists(cxt);
        lscpu_read_cpuinfo(cxt);
        cxt->arch = lscpu_read_architecture(cxt);
 
-       lscpu_read_cpulists(cxt);
        lscpu_read_archext(cxt);
        lscpu_read_vulnerabilities(cxt);
        lscpu_read_numas(cxt);
index 2bf3d59694343c4b76eb357b7c1e5c34f1615d31..ab4a0b0abf3765f502edb2000c8a8ddf93ef0a18 100644 (file)
@@ -62,18 +62,18 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
 
        sys = cxt->syscpu;                              /* /sys/devices/system/cpu/ */
        setsize = CPU_ALLOC_SIZE(cxt->maxcpus);         /* CPU set size */
-       npos = cxt->ncpuspos;                           /* possible CPUs */
+       npos = cxt->npossibles;                         /* 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++) {
+       for (i = 0; i < npos; 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)
+               if (!cpu || cpu->type != ct)
                        continue;
 
                num = cpu->logical_id;
@@ -165,7 +165,7 @@ static int cputype_read_topology(struct lscpu_cxt *cxt, struct lscpu_cputype *ct
        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)
+               if (!ct->ncores_per_socket && ct->nsockets)
                        ct->ncores_per_socket = ct->ncores / ct->nsockets;
                if (!ct->nsockets_per_book && ct->nbooks)
                        ct->nsockets_per_book = ct->nsockets / ct->nbooks;
@@ -200,11 +200,15 @@ 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++) {
+       for (i = 0; i < cxt->npossibles; i++) {
                struct lscpu_cpu *cpu = cxt->cpus[i];
-               int num = cpu->logical_id;
+               int num;
 
-               DBG(TYPE, ul_debugobj(cpu, "#%d reading IDs", num));
+               if (!cpu)
+                       continue;
+
+               num= cpu->logical_id;
+               DBG(CPU, 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;
@@ -224,13 +228,15 @@ int lscpu_read_topology_polarization(struct lscpu_cxt *cxt)
        struct path_cxt *sys = cxt->syscpu;
        size_t i;
 
-       for (i = 0; i < cxt->ncpus; i++) {
+       for (i = 0; i < cxt->npossibles; i++) {
                struct lscpu_cpu *cpu = cxt->cpus[i];
-               int num = cpu->logical_id;
+               int num;
                char mode[64];
 
-               if (!cpu->type || cpu->type->dispatching < 0)
+               if (!cpu || !cpu->type || cpu->type->dispatching < 0)
                        continue;
+
+               num = cpu->logical_id;
                if (ul_path_accessf(sys, F_OK, "cpu%d/polarization", num) != 0)
                        continue;