]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: report more usable cache sizes
authorKarel Zak <kzak@redhat.com>
Tue, 19 Mar 2019 10:09:02 +0000 (11:09 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 19 Mar 2019 10:09:02 +0000 (11:09 +0100)
The current version reports cache size as reported by /sys, it means
real size of the one piece of the cache. This way provides minimal
overview about all system as the cache is often shared between CPUs.

It seems better to report all size of the caches in the summary
output. It also does not make sense to report sizes per core (or
socket) as CPU topology may be pretty complicated.

The final solution (not implemented yet) will be to have --list-caches
where we can report all details like all-size, item-size, per-core size,
ways, type, etc.

Addresses: https://github.com/karelzak/util-linux/issues/663
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/lscpu.c

index 1d78dac3692ac767076d1b6c7f948c7f56241e37..1a03aaf6a7df070f8c47ae8747e406c87d1d7917 100644 (file)
@@ -1699,6 +1699,36 @@ print_cpuset(struct libscols_table *tb,
        }
 }
 
+static int get_cache_full_size(struct lscpu_desc *desc, int idx, uint64_t *res)
+{
+       struct cpu_cache *ca = &desc->caches[idx];
+       size_t setsize = CPU_ALLOC_SIZE(maxcpus);
+       int i, nshares = 0, rc;
+       uint64_t sz;
+
+       /* Convert size to number */
+       rc = parse_size(ca->size, &sz, NULL);
+       if (rc)
+               return rc;
+
+       /* Count number of CPUs which shares the cache */
+       for (i = 0; i < desc->ncpuspos; i++) {
+               int cpu = real_cpu_num(desc, i);
+
+               if (desc->present && !is_cpu_present(desc, cpu))
+                       continue;
+               if (CPU_ISSET_S(cpu, setsize, ca->sharedmaps[0]))
+                       nshares++;
+       }
+
+       /* Correction for CPU threads */
+       if (desc->nthreads > desc->ncores)
+               nshares /= (desc->nthreads / desc->ncores);
+
+       *res = (desc->ncores / nshares) * sz;
+       return 0;
+}
+
 /*
  * default output
  */
@@ -1872,9 +1902,18 @@ print_summary(struct lscpu_desc *desc, struct lscpu_modifier *mod)
                add_summary_s(tb, _("Dispatching mode:"), _(disp_modes[desc->dispatching]));
        if (desc->ncaches) {
                for (i = desc->ncaches - 1; i >= 0; i--) {
+                       uint64_t sz = 0;
+                       char *tmp;
+
+                       if (get_cache_full_size(desc, i, &sz) != 0)
+                               continue;
+                       tmp = size_to_human_string(
+                                       SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE,
+                                       sz);
                        snprintf(buf, sizeof(buf),
-                                       _("%s cache:"), desc->caches[i].name);
-                       add_summary_s(tb, buf, desc->caches[i].size);
+                                       _("%s cache: "), desc->caches[i].name);
+                       add_summary_s(tb, buf, tmp);
+                       free(tmp);
                }
        }
        if (desc->necaches) {