aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/s390-sample-raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/s390-sample-raw.c')
-rw-r--r--tools/perf/util/s390-sample-raw.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sample-raw.c
index 1c5a4d63bc9d..6650f599ed9c 100644
--- a/tools/perf/util/s390-sample-raw.c
+++ b/tools/perf/util/s390-sample-raw.c
@@ -30,6 +30,7 @@
#include "color.h"
#include "sample-raw.h"
#include "s390-cpumcf-kernel.h"
+#include "pmu-events/pmu-events.h"
static size_t ctrset_size(struct cf_ctrset_entry *set)
{
@@ -112,14 +113,61 @@ static void s390_cpumcfdg_dumptrail(const char *color, size_t offset,
te.tod_base, te.mach_type);
}
+/* Return starting number of a counter set */
+static int get_counterset_start(int setnr)
+{
+ switch (setnr) {
+ case CPUMF_CTR_SET_BASIC: /* Basic counter set */
+ return 0;
+ case CPUMF_CTR_SET_USER: /* Problem state counter set */
+ return 32;
+ case CPUMF_CTR_SET_CRYPTO: /* Crypto counter set */
+ return 64;
+ case CPUMF_CTR_SET_EXT: /* Extended counter set */
+ return 128;
+ case CPUMF_CTR_SET_MT_DIAG: /* Diagnostic counter set */
+ return 448;
+ default:
+ return -1;
+ }
+}
+
+/* Scan the PMU table and extract the logical name of a counter from the
+ * PMU events table. Input is the counter set and counter number with in the
+ * set. Construct the event number and use this as key. If they match return
+ * the name of this counter.
+ * If no match is found a NULL pointer is returned.
+ */
+static const char *get_counter_name(int set, int nr, struct pmu_events_map *map)
+{
+ int rc, event_nr, wanted = get_counterset_start(set) + nr;
+
+ if (map) {
+ struct pmu_event *evp = map->table;
+
+ for (; evp->name || evp->event || evp->desc; ++evp) {
+ if (evp->name == NULL || evp->event == NULL)
+ continue;
+ rc = sscanf(evp->event, "event=%x", &event_nr);
+ if (rc == 1 && event_nr == wanted)
+ return evp->name;
+ }
+ }
+ return NULL;
+}
+
static void s390_cpumcfdg_dump(struct perf_sample *sample)
{
size_t i, len = sample->raw_size, offset = 0;
unsigned char *buf = sample->raw_data;
const char *color = PERF_COLOR_BLUE;
struct cf_ctrset_entry *cep, ce;
+ struct pmu_events_map *map;
+ struct perf_pmu pmu;
u64 *p;
+ memset(&pmu, 0, sizeof(pmu));
+ map = perf_pmu__find_map(&pmu);
while (offset < len) {
cep = (struct cf_ctrset_entry *)(buf + offset);
@@ -136,12 +184,13 @@ static void s390_cpumcfdg_dump(struct perf_sample *sample)
color_fprintf(stdout, color, " [%#08zx] Counterset:%d"
" Counters:%d\n", offset, ce.set, ce.ctr);
- for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; i += 2, p += 2)
+ for (i = 0, p = (u64 *)(cep + 1); i < ce.ctr; ++i, ++p) {
+ const char *ev_name = get_counter_name(ce.set, i, map);
+
color_fprintf(stdout, color,
- "\tCounter:%03d Value:%#018lx"
- " Counter:%03d Value:%#018lx\n",
- i, be64_to_cpu(*p),
- i + 1, be64_to_cpu(*(p + 1)));
+ "\tCounter:%03d %s Value:%#018lx\n", i,
+ ev_name ?: "<unknown>", be64_to_cpu(*p));
+ }
offset += ctrset_size(&ce);
}
}