From 718907d9ba17440a74abae0c606973772d91ad95 Mon Sep 17 00:00:00 2001 From: Thomas Richter Date: Wed, 27 Nov 2024 10:33:31 +0100 Subject: [PATCH] cpumf/lswhc: Add short names to lshwc output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add option -s or --short to display the header using a short counter name. With this option the counter symbol names, which can be very long as in IDCW_ON_DRAWER_DRAWER_HIT are replaced by a shorter name. That name consists of an abbrevation for the counter set this counter belongs to and the counter number in that set. The abbrevations are: B --> Basic counter set P --> Problem state counter set C --> Crypto counter set E --> Extended counter set M --> MT_Diagnostic counter set U --> Undefined counter. Display E165 for counter name IDCW_ON_DRAWER_DRAWER_HIT which is counter number 165 from the extended counter set. Signed-off-by: Thomas Richter Signed-off-by: Jan Höppner --- cpumf/lshwc.c | 51 ++++++++++++++++++++++++++++++++++-- include/lib/libcpumf.h | 13 ++++++++++ libcpumf/Makefile | 3 ++- libcpumf/libcpumf_ctrset.c | 53 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 libcpumf/libcpumf_ctrset.c diff --git a/cpumf/lshwc.c b/cpumf/lshwc.c index 8ef61658..bb58bf94 100644 --- a/cpumf/lshwc.c +++ b/cpumf/lshwc.c @@ -55,6 +55,7 @@ static unsigned long loop_count = 1; static unsigned char *ioctlbuffer; static bool allcpu; static char *ctrformat = "%ld"; +static bool shortname; static unsigned int max_possible_cpus; /* No of possible CPUs */ static struct ctrname { /* List of defined counters */ @@ -64,6 +65,38 @@ static struct ctrname { /* List of defined counters */ unsigned long *ccv; /* Per CPU counter value */ } ctrname[MAXCTRS]; +static char *mk_name(int ctr, char *name) +{ + char ctrset[8]; + + if (!shortname) + return util_strdup(name); + + switch (libcpumf_ctrset(ctr, cfvn, csvn)) { + case CPUMF_CTRSET_BASIC: + ctrset[0] = 'B'; + break; + case CPUMF_CTRSET_PROBLEM_STATE: + ctrset[0] = 'P'; + break; + case CPUMF_CTRSET_CRYPTO: + ctrset[0] = 'C'; + break; + case CPUMF_CTRSET_EXTENDED: + ctrset[0] = 'E'; + break; + case CPUMF_CTRSET_MT_DIAG: + ctrset[0] = 'M'; + break; + default: + ctrset[0] = 'U'; + break; + } + sprintf(ctrset, "%c%d", ctrset[0], ctr); + + return util_strdup(ctrset); +} + static bool read_counternames(void) { struct dirent **namelist = NULL; @@ -80,7 +113,7 @@ static bool read_counternames(void) for (i = 0; i < count && ctr >= 0; i++) { util_asprintf(&ctrpath, "%s/%s", path, namelist[i]->d_name); if (util_file_read_va(ctrpath, "event=%x", &ctr) == 1) - ctrname[ctr].name = util_strdup(namelist[i]->d_name); + ctrname[ctr].name = mk_name(ctr, namelist[i]->d_name); else warnx("Cannot parse %s", ctrpath); free(ctrpath); @@ -312,7 +345,14 @@ static void show_header(void) continue; if (comma) putchar(','); - printf("%s(%ld)", ctrname[i].name ?: "Counter", i); + if (shortname) { + if (ctrname[i].name) + printf("%s", ctrname[i].name); + else + printf("U%ld", i); + } else { + printf("%s(%ld)", ctrname[i].name ?: "Counter", i); + } comma = true; } putchar('\n'); @@ -606,6 +646,10 @@ static struct util_opt opt_vec[] = { .argument = "NUMBER", .desc = "Specifies interval between read operations (seconds)" }, + { + .option = { "short", no_argument, NULL, 's' }, + .desc = "Abbreviate counter name with counter set letter and number" + }, { .option = { "hex0x", no_argument, NULL, 'X' }, .desc = "Counter values in hexadecimal format with leading 0x" @@ -674,6 +718,9 @@ int main(int argc, char **argv) if (errno || *slash) errx(EXIT_FAILURE, "Invalid argument for -%c", ch); break; + case 's': + shortname = true; + break; case 'x': ctrformat = "%lx"; break; diff --git a/include/lib/libcpumf.h b/include/lib/libcpumf.h index 65e7b092..e01c4304 100644 --- a/include/lib/libcpumf.h +++ b/include/lib/libcpumf.h @@ -27,6 +27,19 @@ #define CPUMF_CTRSET_CRYPTO 8 #define CPUMF_CTRSET_MT_DIAG 32 +/** + * Return counter set a counter belongs to. + * + * Return the counter set a given counter belongs to, given the + * CPU Measurement facility counter version first and second number. + * + * @param[in] ctr Counter number + * @param[in] cfvn CPUM Counter facility first version number + * @param[in] csvn CPUM Counter facility second version number + * @retval >=0 Counter set number to counter belongs to + */ +int libcpumf_ctrset(int ctr, int cfvn, int csvn); + /** * Read out the PMU type from a given file. * diff --git a/libcpumf/Makefile b/libcpumf/Makefile index 929c3296..1cac23c2 100644 --- a/libcpumf/Makefile +++ b/libcpumf/Makefile @@ -7,7 +7,8 @@ examples = libcpumf_example all: $(lib) examples: $(lib) $(examples) -objects = libcpumf_pmutype.o libcpumf_cpuset.o libcpumf_support.o +objects = libcpumf_pmutype.o libcpumf_cpuset.o libcpumf_support.o \ + libcpumf_ctrset.o $(lib): $(objects) diff --git a/libcpumf/libcpumf_ctrset.c b/libcpumf/libcpumf_ctrset.c new file mode 100644 index 00000000..8585f2de --- /dev/null +++ b/libcpumf/libcpumf_ctrset.c @@ -0,0 +1,53 @@ +/* Copyright IBM Corp. 2022, 2024 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#include +#include +#include +#include +#include + +#include "lib/libcpumf.h" + +int libcpumf_ctrset(int ctr, int cfvn, int csvn) +{ + /* Governs basic and problem state counters */ + switch (cfvn) { + case 1: + if (ctr >= 0 && ctr < 32) + return CPUMF_CTRSET_BASIC; + if (ctr >= 32 && ctr < 38) + return CPUMF_CTRSET_PROBLEM_STATE; + break; + case 3: + if (ctr >= 0 && ctr < 32) + return CPUMF_CTRSET_BASIC; + if (ctr >= 32 && ctr < 34) + return CPUMF_CTRSET_PROBLEM_STATE; + break; + } + + /* Governs crypto, extended and MT-Diagnositc counters */ + switch (csvn) { + case 1 ... 5: + if (ctr >= 64 && ctr < 80) + return CPUMF_CTRSET_CRYPTO; + if ((csvn == 1 && ctr >= 128 && ctr < 160) || + (csvn == 2 && ctr >= 128 && ctr < 176) || + (ctr >= 128 && ctr < 256)) + return CPUMF_CTRSET_EXTENDED; + break; + case 6 ... 8: + if (ctr >= 64 && ctr < 84) + return CPUMF_CTRSET_CRYPTO; + if (ctr >= 128 && ctr < 288) + return CPUMF_CTRSET_EXTENDED; + break; + } + if (csvn >= 3 && ctr >= 448 && ctr < 496) + return CPUMF_CTRSET_MT_DIAG; + return CPUMF_CTRSET_NONE; +}