summaryrefslogtreecommitdiff
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2023-05-02 15:38:40 -0700
committerArnaldo Carvalho de Melo <acme@redhat.com>2023-05-15 09:12:14 -0300
commit5ea8f2ccffb23983f02012a2731464586b10fbf3 (patch)
treede537dab242f66972f49236be36de96913110ecd /tools/perf/util/parse-events.c
parentaefde50a446b56f592a589e12e89935bea3b85f9 (diff)
downloadlinux-5ea8f2ccffb23983f02012a2731464586b10fbf3.tar.gz
linux-5ea8f2ccffb23983f02012a2731464586b10fbf3.tar.bz2
linux-5ea8f2ccffb23983f02012a2731464586b10fbf3.zip
perf parse-events: Support hardware events as terms
An event like "cpu/instructions/" typically parses due to there being a sysfs event called instructions. On hybrid recursive parsing means that the hardware event is encoded in the attribute, with the PMU being placed in the high bits of the config: ''' $ perf stat -vv -e 'cpu_core/cycles/' true ... ------------------------------------------------------------ perf_event_attr: size 136 config 0x400000000 sample_type IDENTIFIER read_format TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING disabled 1 inherit 1 enable_on_exec 1 exclude_guest 1 ------------------------------------------------------------ ''' Make this behavior the default by adding a new term type and token for hardware events. The token gathers both the numeric config and the parsed name, so that if the token appears like "cycles/name=cycles/" then the token can be handled like a name. The numeric value isn't sufficient to distinguish say "cpu-cycles" from "cycles". Extend the parse-events test so that all current non-PMU hardware parsing tests, also test with the PMU cpu - more than half the change. Signed-off-by: Ian Rogers <irogers@google.com> Tested-by: Kan Liang <kan.liang@linux.intel.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ahmad Yasin <ahmad.yasin@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Cc: Caleb Biggers <caleb.biggers@intel.com> Cc: Edward Baker <edward.baker@intel.com> Cc: Florian Fischer <florian.fischer@muhq.space> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@arm.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: John Garry <john.g.garry@oracle.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Kang Minchul <tegongkang@gmail.com> Cc: Leo Yan <leo.yan@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Perry Taylor <perry.taylor@intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@amd.com> Cc: Rob Herring <robh@kernel.org> Cc: Samantha Alt <samantha.alt@intel.com> Cc: Stephane Eranian <eranian@google.com> Cc: Sumanth Korikkar <sumanthk@linux.ibm.com> Cc: Suzuki Poulouse <suzuki.poulose@arm.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Tiezhu Yang <yangtiezhu@loongson.cn> Cc: Weilin Wang <weilin.wang@intel.com> Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com> Cc: Yang Jihong <yangjihong1@huawei.com> Link: https://lore.kernel.org/r/20230502223851.2234828-34-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c37
1 files changed, 12 insertions, 25 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index d9d964bbc0e2..dea27bc0b376 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1052,6 +1052,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
[PARSE_EVENTS__TERM_TYPE_METRIC_ID] = "metric-id",
[PARSE_EVENTS__TERM_TYPE_RAW] = "raw",
[PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE] = "legacy-cache",
+ [PARSE_EVENTS__TERM_TYPE_HARDWARE] = "hardware",
};
static bool config_term_shrinked;
@@ -1239,6 +1240,17 @@ static int config_term_pmu(struct perf_event_attr *attr,
} else
term->type_term = PARSE_EVENTS__TERM_TYPE_USER;
}
+ if (term->type_term == PARSE_EVENTS__TERM_TYPE_HARDWARE) {
+ const struct perf_pmu *pmu = perf_pmu__find_by_type(attr->type);
+
+ if (!pmu) {
+ pr_debug("Failed to find PMU for type %d", attr->type);
+ return -EINVAL;
+ }
+ attr->type = PERF_TYPE_HARDWARE;
+ attr->config = ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT) | term->val.num;
+ return 0;
+ }
if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER ||
term->type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG) {
/*
@@ -2569,31 +2581,6 @@ int parse_events_term__str(struct parse_events_term **term,
return new_term(term, &temp, str, 0);
}
-int parse_events_term__sym_hw(struct parse_events_term **term,
- char *config, unsigned idx)
-{
- struct event_symbol *sym;
- char *str;
- struct parse_events_term temp = {
- .type_val = PARSE_EVENTS__TERM_TYPE_STR,
- .type_term = PARSE_EVENTS__TERM_TYPE_USER,
- .config = config,
- };
-
- if (!temp.config) {
- temp.config = strdup("event");
- if (!temp.config)
- return -ENOMEM;
- }
- BUG_ON(idx >= PERF_COUNT_HW_MAX);
- sym = &event_symbols_hw[idx];
-
- str = strdup(sym->symbol);
- if (!str)
- return -ENOMEM;
- return new_term(term, &temp, str, 0);
-}
-
int parse_events_term__clone(struct parse_events_term **new,
struct parse_events_term *term)
{