^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Support for libpfm4 event encoding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2020 Google LLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "util/cpumap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "util/debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "util/event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "util/evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "util/evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "util/parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "util/pmu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "util/pfm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <perfmon/pfmlib_perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static void libpfm_initialize(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) ret = pfm_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (ret != PFM_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ui__warning("libpfm failed to initialize: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) pfm_strerror(ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int parse_libpfm_events_option(const struct option *opt, const char *str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct evlist *evlist = *(struct evlist **)opt->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct perf_pmu *pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct evsel *evsel, *grp_leader = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) char *p, *q, *p_orig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) const char *sep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) int grp_evt = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) libpfm_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) p_orig = p = strdup(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * force loading of the PMU list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) perf_pmu__scan(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) for (q = p; strsep(&p, ",{}"); q = p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) sep = p ? str + (p - p_orig - 1) : "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (*sep == '{') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (grp_evt > -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) ui__error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "nested event groups not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) grp_evt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* no event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (*q == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) memset(&attr, 0, sizeof(attr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) event_attr_init(&attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ret = pfm_get_perf_event_encoding(q, PFM_PLM0|PFM_PLM3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) &attr, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (ret != PFM_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ui__error("failed to parse event %s : %s\n", str,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pfm_strerror(ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) pmu = perf_pmu__find_by_type((unsigned int)attr.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) evsel = parse_events__add_event(evlist->core.nr_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) &attr, q, pmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (evsel == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) evsel->is_libpfm_event = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) evlist__add(evlist, evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (grp_evt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) grp_leader = evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (grp_evt > -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) evsel->leader = grp_leader;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) grp_leader->core.nr_members++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) grp_evt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (*sep == '}') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (grp_evt < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ui__error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) "cannot close a non-existing event group\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) evlist->nr_groups++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) grp_leader = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) grp_evt = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) free(p_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static const char *srcs[PFM_ATTR_CTRL_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) [PFM_ATTR_CTRL_UNKNOWN] = "???",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) [PFM_ATTR_CTRL_PMU] = "PMU",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) [PFM_ATTR_CTRL_PERF_EVENT] = "perf_event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) print_attr_flags(pfm_event_attr_info_t *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (info->is_dfl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) printf("[default] ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (info->is_precise) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) printf("[precise] ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (!n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) printf("- ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) print_libpfm_events_detailed(pfm_event_info_t *info, bool long_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) pfm_event_attr_info_t ainfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) const char *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int j, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) ainfo.size = sizeof(ainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) printf(" %s\n", info->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) printf(" [%s]\n", info->desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (long_desc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (info->equiv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) printf(" Equiv: %s\n", info->equiv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) printf(" Code : 0x%"PRIx64"\n", info->code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) pfm_for_each_event_attr(j, info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = pfm_get_event_attr_info(info->idx, j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) PFM_OS_PERF_EVENT_EXT, &ainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (ret != PFM_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (ainfo.type == PFM_ATTR_UMASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) printf(" %s:%s\n", info->name, ainfo.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) printf(" [%s]\n", ainfo.desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (!long_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) src = srcs[ainfo.ctrl];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) switch (ainfo.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case PFM_ATTR_UMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) printf(" Umask : 0x%02"PRIx64" : %s: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ainfo.code, src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) print_attr_flags(&ainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) putchar('\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case PFM_ATTR_MOD_BOOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) printf(" Modif : %s: [%s] : %s (boolean)\n", src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ainfo.name, ainfo.desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case PFM_ATTR_MOD_INTEGER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) printf(" Modif : %s: [%s] : %s (integer)\n", src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ainfo.name, ainfo.desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case PFM_ATTR_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case PFM_ATTR_RAW_UMASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case PFM_ATTR_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) printf(" Attr : %s: [%s] : %s\n", src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ainfo.name, ainfo.desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * list all pmu::event:umask, pmu::event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * printed events may not be all valid combinations of umask for an event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) print_libpfm_events_raw(pfm_pmu_info_t *pinfo, pfm_event_info_t *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) pfm_event_attr_info_t ainfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int j, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) bool has_umask = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ainfo.size = sizeof(ainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pfm_for_each_event_attr(j, info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = pfm_get_event_attr_info(info->idx, j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) PFM_OS_PERF_EVENT_EXT, &ainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ret != PFM_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (ainfo.type != PFM_ATTR_UMASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) printf("%s::%s:%s\n", pinfo->name, info->name, ainfo.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) has_umask = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!has_umask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) printf("%s::%s\n", pinfo->name, info->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) void print_libpfm_events(bool name_only, bool long_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) pfm_event_info_t info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pfm_pmu_info_t pinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int i, p, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) libpfm_initialize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* initialize to zero to indicate ABI version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) info.size = sizeof(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) pinfo.size = sizeof(pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) puts("\nList of pre-defined events (to be used in --pfm-events):\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) pfm_for_all_pmus(p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) bool printed_pmu = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ret = pfm_get_pmu_info(p, &pinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (ret != PFM_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* only print events that are supported by host HW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (!pinfo.is_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /* handled by perf directly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (pinfo.pmu == PFM_PMU_PERF_EVENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) for (i = pinfo.first_event; i != -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) i = pfm_get_event_next(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) ret = pfm_get_event_info(i, PFM_OS_PERF_EVENT_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret != PFM_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!name_only && !printed_pmu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) printf("%s:\n", pinfo.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) printed_pmu = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!name_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) print_libpfm_events_detailed(&info, long_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) print_libpfm_events_raw(&pinfo, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (!name_only && printed_pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) putchar('\n');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }