]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lscpu: add SCALMHZ% and "CPU scaling MHz:"
authorKarel Zak <kzak@redhat.com>
Mon, 24 May 2021 10:24:33 +0000 (12:24 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 24 May 2021 11:39:53 +0000 (13:39 +0200)
$ lscpu
...
  Model name:           Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
    CPU family:         6
    Model:              60
    Thread(s) per core: 2
    Core(s) per socket: 4
    Socket(s):          1
    Stepping:           3
    CPU(s) scaling MHz: 61%
    CPU max MHz:        4400.0000
    CPU min MHz:        800.0000
...

$ lscpu -e=CPU,MAXMHZ,MINMHZ,MHZ,SCALMHZ%
CPU    MAXMHZ   MINMHZ      MHZ SCALMHZ%
  0 4400.0000 800.0000 2800.000      64%
  1 4400.0000 800.0000 4000.146      91%
  2 4400.0000 800.0000 2800.000      64%
  3 4400.0000 800.0000 2800.000      64%
  4 4400.0000 800.0000 2800.000      64%
  5 4400.0000 800.0000 4400.000     100%
  6 4400.0000 800.0000  800.000      18%
  7 4400.0000 800.0000 2800.000      64%

Addresses: https://github.com/karelzak/util-linux/issues/1314
Signed-off-by: Karel Zak <kzak@redhat.com>
Documentation/TODO
sys-utils/lscpu-cputype.c
sys-utils/lscpu-topology.c
sys-utils/lscpu.c
sys-utils/lscpu.h

index 33ffa189deb85204709561874e2e71de4a184ab6..e382e4b973a492af27abdb67a5caad6a071fbcc0 100644 (file)
@@ -53,6 +53,7 @@ cal
 
 lscpu
 -----
+  - add --freq output to visualise CPU use, see https://github.com/karelzak/util-linux/issues/1314
   - read cpuid and uname information from file if --sysroot is specified, then
     we can prepare regression tests completely independent on hw and architecture.
 
index 834e1c663213d17acfc5068eb4f2a63c1259be96..c2c1dc37632d7231eee4e011a8a9e339d37586c0 100644 (file)
@@ -510,6 +510,12 @@ int lscpu_read_cpuinfo(struct lscpu_cxt *cxt)
                                pr->curr_type->static_mhz = xstrdup(value);
                        if (pattern->id == PAT_BOGOMIPS_CPU && pr->curr_type && !pr->curr_type->bogomips)
                                pr->curr_type->bogomips = xstrdup(value);
+                       if (pattern->id == PAT_MHZ && pr->curr_cpu && value) {
+                               errno = 0;
+                               pr->curr_cpu->mhz_cur_freq = strtof(value, NULL);
+                               if (errno)
+                                       pr->curr_cpu->mhz_cur_freq = 0;
+                       }
                        break;
                case CPUINFO_LINE_CPUTYPE:
                        if (pr->curr_type && is_different_cputype(pr->curr_type, pattern->offset, value)) {
index 485c17485fc70a094f30ba6824ccb1657a815882..328ee7cbc2323a8b1fc872d77ec1aa534b59cb51 100644 (file)
@@ -583,6 +583,27 @@ float lsblk_cputype_get_minmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct)
        return res;
 }
 
+/* returns scaling (use) of CPUs freq. in percent */
+float lsblk_cputype_get_scalmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct)
+{
+       size_t i;
+       float fmax = 0, fcur = 0;
+
+       for (i = 0; i < cxt->npossibles; i++) {
+               struct lscpu_cpu *cpu = cxt->cpus[i];
+
+               if (!cpu || cpu->type != ct || !is_cpu_present(cxt, cpu))
+                       continue;
+               if (cpu->mhz_max_freq <= 0.0 || cpu->mhz_cur_freq <= 0.0)
+                       continue;
+               fmax += cpu->mhz_max_freq;
+               fcur += cpu->mhz_cur_freq;
+       }
+       if (fcur <= 0.0)
+               return 0.0;
+       return fcur / fmax * 100;
+}
+
 int lscpu_read_topology(struct lscpu_cxt *cxt)
 {
        size_t i;
index 29afd91163e4a17425742364e9eaedc0e74ea1d5..5fba083293ffdc52c089d8444cb36fca20f297ed 100644 (file)
@@ -105,6 +105,7 @@ enum {
        COL_CPU_CONFIGURED,
        COL_CPU_ONLINE,
        COL_CPU_MHZ,
+       COL_CPU_SCALMHZ,
        COL_CPU_MAXMHZ,
        COL_CPU_MINMHZ,
 };
@@ -150,6 +151,7 @@ static struct lscpu_coldesc coldescs_cpu[] =
        [COL_CPU_CONFIGURED]   = { "CONFIGURED", N_("shows if the hypervisor has allocated the CPU") },
        [COL_CPU_ONLINE]       = { "ONLINE", N_("shows if Linux currently makes use of the CPU"), SCOLS_FL_RIGHT },
        [COL_CPU_MHZ]          = { "MHZ", N_("shows the currently MHz of the CPU"), SCOLS_FL_RIGHT },
+       [COL_CPU_SCALMHZ]      = { "SCALMHZ%", N_("shows scaling percentage of the CPU frequency"), SCOLS_FL_RIGHT },
        [COL_CPU_MAXMHZ]       = { "MAXMHZ", N_("shows the maximum MHz of the CPU"), SCOLS_FL_RIGHT },
        [COL_CPU_MINMHZ]       = { "MINMHZ", N_("shows the minimum MHz of the CPU"), SCOLS_FL_RIGHT }
 };
@@ -425,6 +427,10 @@ static char *get_cell_data(
                if (cpu->mhz)
                        xstrncpy(buf, cpu->mhz, bufsz);
                break;
+       case COL_CPU_SCALMHZ:
+               if (cpu->mhz_cur_freq && cpu->mhz_max_freq)
+                       snprintf(buf, bufsz, "%.0f%%", cpu->mhz_cur_freq / cpu->mhz_max_freq * 100);
+               break;
        case COL_CPU_MAXMHZ:
                if (cpu->mhz_max_freq)
                        snprintf(buf, bufsz, "%.4f", cpu->mhz_max_freq);
@@ -890,6 +896,9 @@ print_summary_cputype(struct lscpu_cxt *cxt,
                add_summary_s(tb, sec, _("CPU static MHz:"), ct->static_mhz);
 
        if (ct->has_freq) {
+               float scal = lsblk_cputype_get_scalmhz(cxt, ct);
+               if (scal > 0.0)
+                       add_summary_x(tb, sec, _("CPU(s) scaling MHz:"), "%.0f%%", scal);
                add_summary_x(tb, sec, _("CPU max MHz:"), "%.4f", lsblk_cputype_get_maxmhz(cxt, ct));
                add_summary_x(tb, sec, _("CPU min MHz:"), "%.4f", lsblk_cputype_get_minmhz(cxt, ct));
        }
index e52c77c226c00baffded42448e31319e78e1ebd8..62f5325810265d7977dded70b6d09e2061aa6c07 100644 (file)
@@ -127,11 +127,12 @@ struct lscpu_cpu {
        int logical_id;
 
        char    *bogomips;      /* per-CPU bogomips */
-       char    *mhz;           /* max freq from cpuinfo */
+       char    *mhz;           /* freq from cpuinfo */
        char    *dynamic_mhz;   /* from cpuinf for s390 */
        char    *static_mhz;    /* from cpuinf for s390 */
        float   mhz_max_freq;   /* realtime freq from /sys/.../cpuinfo_max_freq */
        float   mhz_min_freq;   /* realtime freq from /sys/.../cpuinfo_min_freq */
+       float   mhz_cur_freq;
 
        int     coreid;
        int     socketid;
@@ -280,6 +281,7 @@ void lscpu_cputype_free_topology(struct lscpu_cputype *ct);
 
 float lsblk_cputype_get_maxmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
 float lsblk_cputype_get_minmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
+float lsblk_cputype_get_scalmhz(struct lscpu_cxt *cxt, struct lscpu_cputype *ct);
 
 struct lscpu_arch *lscpu_read_architecture(struct lscpu_cxt *cxt);
 void lscpu_free_architecture(struct lscpu_arch *ar);