From: Ian Rogers <irogers@google.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
Kan Liang <kan.liang@linux.intel.com>,
Ahmad Yasin <ahmad.yasin@intel.com>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Stephane Eranian <eranian@google.com>,
Andi Kleen <ak@linux.intel.com>,
Perry Taylor <perry.taylor@intel.com>,
Samantha Alt <samantha.alt@intel.com>,
Caleb Biggers <caleb.biggers@intel.com>,
Weilin Wang <weilin.wang@intel.com>,
Edward Baker <edward.baker@intel.com>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
Adrian Hunter <adrian.hunter@intel.com>,
Florian Fischer <florian.fischer@muhq.space>,
Rob Herring <robh@kernel.org>,
Zhengjun Xing <zhengjun.xing@linux.intel.com>,
John Garry <john.g.garry@oracle.com>,
Kajol Jain <kjain@linux.ibm.com>,
Sumanth Korikkar <sumanthk@linux.ibm.com>,
Thomas Richter <tmricht@linux.ibm.com>,
Tiezhu Yang <yangtiezhu@loongson.cn>,
Ravi Bangoria <ravi.bangoria@amd.com>,
Leo Yan <leo.yan@linaro.org>,
Yang Jihong <yangjihong1@huawei.com>,
James Clark <james.clark@arm.com>,
Suzuki Poulouse <suzuki.poulose@arm.com>,
Kang Minchul <tegongkang@gmail.com>,
Athira Rajeev <atrajeev@linux.vnet.ibm.com>,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Ian Rogers <irogers@google.com>
Subject: [PATCH v4 23/44] perf parse-events: Support PMUs for legacy cache events
Date: Tue, 2 May 2023 15:38:30 -0700 [thread overview]
Message-ID: <20230502223851.2234828-24-irogers@google.com> (raw)
In-Reply-To: <20230502223851.2234828-1-irogers@google.com>
Allow a legacy cache event to be both, for example,
"L1-dcache-load-miss" and "cpu/L1-dcache-load-miss/" by introducing a
new legacy cache term type. The term type is processed in
config_term_pmu, setting both the type in perf_event_attr and the
config. The code to determine the config is factored out of
parse_events_add_cache and shared. If the PMU doesn't support legacy
events, currently just core/hybrid PMUs do, then the term is treated
like a PE_NAME term - as before. If only terms are being parsed, such
as for perf_pmu__new_alias, then the PE_LEGACY_CACHE token is always
parsed as PE_NAME.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/tests/parse-events.c | 18 +++++++++
tools/perf/util/parse-events.c | 70 ++++++++++++++++++++++-----------
tools/perf/util/parse-events.h | 3 ++
tools/perf/util/parse-events.l | 9 ++++-
tools/perf/util/parse-events.y | 14 ++++++-
tools/perf/util/pmu.c | 5 +++
tools/perf/util/pmu.h | 1 +
7 files changed, 96 insertions(+), 24 deletions(-)
diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index 43c0778983e5..c3afd0b129bb 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -1875,6 +1875,24 @@ static const struct evlist_test test__events_pmu[] = {
.check = test__checkevent_raw_pmu,
/* 5 */
},
+ {
+ .name = "cpu/L1-dcache-load-miss/",
+ .valid = test__pmu_cpu_valid,
+ .check = test__checkevent_genhw,
+ /* 6 */
+ },
+ {
+ .name = "cpu/L1-dcache-load-miss/kp",
+ .valid = test__pmu_cpu_valid,
+ .check = test__checkevent_genhw_modifier,
+ /* 7 */
+ },
+ {
+ .name = "cpu/L1-dcache-misses,name=cachepmu/",
+ .valid = test__pmu_cpu_valid,
+ .check = test__checkevent_config_cache,
+ /* 8 */
+ },
};
struct terms_test {
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index b5d95fce520c..f692dd953593 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -404,33 +404,27 @@ static int config_attr(struct perf_event_attr *attr,
struct parse_events_error *err,
config_term_func_t config_term);
-int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
- struct parse_events_error *err,
- struct list_head *head_config,
- struct parse_events_state *parse_state)
+/**
+ * parse_events__decode_legacy_cache - Search name for the legacy cache event
+ * name composed of 1, 2 or 3 hyphen
+ * separated sections. The first section is
+ * the cache type while the others are the
+ * optional op and optional result. To make
+ * life hard the names in the table also
+ * contain hyphens and the longest name
+ * should always be selected.
+ */
+static int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config)
{
- struct perf_event_attr attr;
- LIST_HEAD(config_terms);
- const char *config_name, *metric_id;
- int cache_type = -1, cache_op = -1, cache_result = -1;
- int ret, len;
+ int len, cache_type = -1, cache_op = -1, cache_result = -1;
const char *name_end = &name[strlen(name) + 1];
- bool hybrid;
const char *str = name;
- /*
- * Search str for the legacy cache event name composed of 1, 2 or 3
- * hyphen separated sections. The first section is the cache type while
- * the others are the optional op and optional result. To make life hard
- * the names in the table also contain hyphens and the longest name
- * should always be selected.
- */
cache_type = parse_aliases(str, evsel__hw_cache, PERF_COUNT_HW_CACHE_MAX, &len);
if (cache_type == -1)
return -EINVAL;
str += len + 1;
- config_name = get_config_name(head_config);
if (str < name_end) {
cache_op = parse_aliases(str, evsel__hw_cache_op,
PERF_COUNT_HW_CACHE_OP_MAX, &len);
@@ -471,9 +465,28 @@ int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
if (cache_result == -1)
cache_result = PERF_COUNT_HW_CACHE_RESULT_ACCESS;
+ *config = ((__u64)pmu_type << PERF_PMU_TYPE_SHIFT) |
+ cache_type | (cache_op << 8) | (cache_result << 16);
+ return 0;
+}
+
+int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
+ struct parse_events_error *err,
+ struct list_head *head_config,
+ struct parse_events_state *parse_state)
+{
+ struct perf_event_attr attr;
+ LIST_HEAD(config_terms);
+ const char *config_name, *metric_id;
+ int ret;
+ bool hybrid;
+
+
memset(&attr, 0, sizeof(attr));
- attr.config = cache_type | (cache_op << 8) | (cache_result << 16);
attr.type = PERF_TYPE_HW_CACHE;
+ ret = parse_events__decode_legacy_cache(name, /*pmu_type=*/0, &attr.config);
+ if (ret)
+ return ret;
if (head_config) {
if (config_attr(&attr, head_config, err,
@@ -484,6 +497,7 @@ int parse_events_add_cache(struct list_head *list, int *idx, const char *name,
return -ENOMEM;
}
+ config_name = get_config_name(head_config);
metric_id = get_config_metric_id(head_config);
ret = parse_events__add_cache_hybrid(list, idx, &attr,
config_name ? : name,
@@ -1022,6 +1036,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = {
[PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE] = "aux-sample-size",
[PARSE_EVENTS__TERM_TYPE_METRIC_ID] = "metric-id",
[PARSE_EVENTS__TERM_TYPE_RAW] = "raw",
+ [PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE] = "legacy-cache",
};
static bool config_term_shrinked;
@@ -1199,15 +1214,25 @@ static int config_term_pmu(struct perf_event_attr *attr,
struct parse_events_term *term,
struct parse_events_error *err)
{
+ if (term->type_term == PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE) {
+ const struct perf_pmu *pmu = perf_pmu__find_by_type(attr->type);
+
+ if (perf_pmu__supports_legacy_cache(pmu)) {
+ attr->type = PERF_TYPE_HW_CACHE;
+ return parse_events__decode_legacy_cache(term->config, pmu->type,
+ &attr->config);
+ } else
+ term->type_term = PARSE_EVENTS__TERM_TYPE_USER;
+ }
if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER ||
- term->type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG)
+ term->type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG) {
/*
* Always succeed for sysfs terms, as we dont know
* at this point what type they need to have.
*/
return 0;
- else
- return config_term_common(attr, term, err);
+ }
+ return config_term_common(attr, term, err);
}
#ifdef HAVE_LIBTRACEEVENT
@@ -2147,6 +2172,7 @@ int __parse_events(struct evlist *evlist, const char *str,
.evlist = evlist,
.stoken = PE_START_EVENTS,
.fake_pmu = fake_pmu,
+ .match_legacy_cache_terms = true,
};
int ret;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index f638542c8638..5acb62c2e00a 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -71,6 +71,7 @@ enum {
PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE,
PARSE_EVENTS__TERM_TYPE_METRIC_ID,
PARSE_EVENTS__TERM_TYPE_RAW,
+ PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE,
__PARSE_EVENTS__TERM_TYPE_NR,
};
@@ -122,6 +123,8 @@ struct parse_events_state {
int stoken;
struct perf_pmu *fake_pmu;
char *hybrid_pmu_name;
+ /* Should PE_LEGACY_NAME tokens be generated for config terms? */
+ bool match_legacy_cache_terms;
bool wild_card_pmus;
};
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 4b35c099189a..abe0ce681d29 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -63,6 +63,11 @@ static int str(yyscan_t scanner, int token)
return token;
}
+static int lc_str(yyscan_t scanner, const struct parse_events_state *state)
+{
+ return str(scanner, state->match_legacy_cache_terms ? PE_LEGACY_CACHE : PE_NAME);
+}
+
static bool isbpf_suffix(char *text)
{
int len = strlen(text);
@@ -185,7 +190,6 @@ lc_op_result (load|loads|read|store|stores|write|prefetch|prefetches|speculative
%{
struct parse_events_state *_parse_state = parse_events_get_extra(yyscanner);
-
{
int start_token = _parse_state->stoken;
@@ -269,6 +273,9 @@ r{num_raw_hex} { return str(yyscanner, PE_RAW); }
r0x{num_raw_hex} { return str(yyscanner, PE_RAW); }
, { return ','; }
"/" { BEGIN(INITIAL); return '/'; }
+{lc_type} { return lc_str(yyscanner, _parse_state); }
+{lc_type}-{lc_op_result} { return lc_str(yyscanner, _parse_state); }
+{lc_type}-{lc_op_result}-{lc_op_result} { return lc_str(yyscanner, _parse_state); }
{name_minus} { return str(yyscanner, PE_NAME); }
\[all\] { return PE_ARRAY_ALL; }
"[" { BEGIN(array); return '['; }
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index e7072b5601c5..f84fa1b132b3 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -723,7 +723,7 @@ event_term
$$ = head;
}
-name_or_raw: PE_RAW | PE_NAME
+name_or_raw: PE_RAW | PE_NAME | PE_LEGACY_CACHE
event_term:
PE_RAW
@@ -775,6 +775,18 @@ name_or_raw '=' PE_VALUE_SYM_HW
$$ = term;
}
|
+PE_LEGACY_CACHE
+{
+ struct parse_events_term *term;
+
+ if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE,
+ $1, 1, true, &@1, NULL)) {
+ free($1);
+ YYABORT;
+ }
+ $$ = term;
+}
+|
PE_NAME
{
struct parse_events_term *term;
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index cb33d869f1ed..63071d876190 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -1650,6 +1650,11 @@ bool is_pmu_core(const char *name)
return !strcmp(name, "cpu") || is_arm_pmu_core(name);
}
+bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu)
+{
+ return is_pmu_core(pmu->name) || perf_pmu__is_hybrid(pmu->name);
+}
+
static bool pmu_alias_is_duplicate(struct sevent *alias_a,
struct sevent *alias_b)
{
diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h
index b9a02dedd473..05702bc4bcf8 100644
--- a/tools/perf/util/pmu.h
+++ b/tools/perf/util/pmu.h
@@ -220,6 +220,7 @@ void perf_pmu__del_formats(struct list_head *formats);
struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu);
bool is_pmu_core(const char *name);
+bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu);
void print_pmu_events(const struct print_callbacks *print_cb, void *print_state);
bool pmu_have_event(const char *pname, const char *name);
--
2.40.1.495.gc816e09b53d-goog
next prev parent reply other threads:[~2023-05-02 22:42 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-02 22:38 [PATCH v4 00/44] Fix perf on Intel hybrid CPUs Ian Rogers
2023-05-02 22:38 ` [PATCH v4 01/44] perf metric: Change divide by zero and !support events behavior Ian Rogers
2023-05-03 20:57 ` Liang, Kan
2023-05-02 22:38 ` [PATCH v4 02/44] perf stat: Introduce skippable evsels Ian Rogers
2023-05-03 20:57 ` Liang, Kan
2023-05-02 22:38 ` [PATCH v4 04/44] perf parse-events: Don't reorder ungrouped events by pmu Ian Rogers
2023-05-03 20:58 ` Liang, Kan
2023-05-02 22:38 ` [PATCH v4 05/44] perf vendor events intel: Add alderlake metric constraints Ian Rogers
2023-05-02 22:38 ` [PATCH v4 06/44] perf vendor events intel: Add icelake " Ian Rogers
2023-05-02 22:38 ` [PATCH v4 07/44] perf vendor events intel: Add icelakex " Ian Rogers
2023-05-02 22:38 ` [PATCH v4 08/44] perf vendor events intel: Add sapphirerapids " Ian Rogers
2023-05-02 22:38 ` [PATCH v4 09/44] perf vendor events intel: Add tigerlake " Ian Rogers
2023-05-02 22:38 ` [PATCH v4 10/44] perf test: Test more sysfs events Ian Rogers
2023-05-02 22:38 ` [PATCH v4 11/44] perf test: Use valid for PMU tests Ian Rogers
2023-05-02 22:38 ` [PATCH v4 12/44] perf test: Mask configs with extended types then test Ian Rogers
2023-05-02 22:38 ` [PATCH v4 13/44] perf test: Test more with config_cache Ian Rogers
2023-05-02 22:38 ` [PATCH v4 14/44] perf test: Roundtrip name, don't assume 1 event per name Ian Rogers
2023-05-02 22:38 ` [PATCH v4 15/44] perf parse-events: Set attr.type to PMU type early Ian Rogers
2023-05-02 22:38 ` [PATCH v4 16/44] perf parse-events: Set pmu_name whenever a pmu is given Ian Rogers
2023-05-02 22:38 ` [PATCH v4 17/44] perf print-events: Avoid unnecessary strlist Ian Rogers
2023-05-02 22:38 ` [PATCH v4 18/44] perf parse-events: Avoid scanning PMUs before parsing Ian Rogers
2023-05-02 22:38 ` [PATCH v4 19/44] perf evsel: Modify group pmu name for software events Ian Rogers
2023-05-02 22:38 ` [PATCH v4 20/44] perf test: Move x86 hybrid tests to arch/x86 Ian Rogers
2023-05-02 22:38 ` [PATCH v4 21/44] perf test x86 hybrid: Update test expectations Ian Rogers
2023-05-02 22:38 ` [PATCH v4 22/44] perf test x86 hybrid: Add hybrid extended type checks Ian Rogers
2023-05-02 22:38 ` Ian Rogers [this message]
2023-05-02 22:38 ` [PATCH v4 24/44] perf parse-events: Wildcard legacy cache events Ian Rogers
2023-05-02 22:38 ` [PATCH v4 25/44] perf print-events: Print legacy cache events for each PMU Ian Rogers
2023-05-02 22:38 ` [PATCH v4 26/44] perf parse-events: Support wildcards on raw events Ian Rogers
2023-05-02 22:38 ` [PATCH v4 27/44] perf parse-events: Remove now unused hybrid logic Ian Rogers
2023-05-02 22:38 ` [PATCH v4 28/44] perf parse-events: Minor type safety cleanup Ian Rogers
2023-05-02 22:38 ` [PATCH v4 29/44] perf parse-events: Add pmu filter Ian Rogers
2023-05-02 22:38 ` [PATCH v4 30/44] perf stat: Make cputype filter generic Ian Rogers
2023-05-02 22:38 ` [PATCH v4 31/44] perf test: Add cputype testing to perf stat Ian Rogers
2023-05-02 22:38 ` [PATCH v4 32/44] perf test: Fix parse-events tests for >1 core PMU Ian Rogers
2023-05-02 22:38 ` [PATCH v4 33/44] perf parse-events: Support hardware events as terms Ian Rogers
2023-05-02 22:38 ` [PATCH v4 34/44] perf parse-events: Avoid error when assigning a term Ian Rogers
2023-05-02 22:38 ` [PATCH v4 35/44] perf parse-events: Avoid error when assigning a legacy cache term Ian Rogers
2023-05-02 22:38 ` [PATCH v4 36/44] perf parse-events: Don't auto merge hybrid wildcard events Ian Rogers
2023-05-02 22:38 ` [PATCH v4 37/44] perf parse-events: Don't reorder atom cpu events Ian Rogers
2023-05-02 22:38 ` [PATCH v4 38/44] perf metrics: Be PMU specific for referenced metrics Ian Rogers
2023-05-02 22:38 ` [PATCH v4 39/44] perf stat: Command line PMU metric filtering Ian Rogers
2023-05-02 22:38 ` [PATCH v4 40/44] perf vendor events intel: Correct alderlake metrics Ian Rogers
2023-05-02 22:38 ` [PATCH v4 41/44] perf jevents: Don't rewrite metrics across PMUs Ian Rogers
2023-05-02 22:38 ` [PATCH v4 42/44] perf metrics: Be PMU specific in event match Ian Rogers
2023-05-02 22:38 ` [PATCH v4 43/44] perf stat: Don't disable TopdownL1 metric on hybrid Ian Rogers
2023-05-02 22:38 ` [PATCH v4 44/44] perf parse-events: Reduce scope of is_event_supported Ian Rogers
2023-05-03 20:56 ` [PATCH v4 00/44] Fix perf on Intel hybrid CPUs Liang, Kan
2023-05-12 18:33 ` Arnaldo Carvalho de Melo
2023-05-14 12:03 ` Liang, Kan
2023-05-15 12:14 ` Arnaldo Carvalho de Melo
2023-05-15 22:49 ` Ian Rogers
2023-05-16 18:19 ` Arnaldo Carvalho de Melo
2023-05-09 18:09 ` Arnaldo Carvalho de Melo
2023-05-12 18:28 ` Arnaldo Carvalho de Melo
2023-05-13 6:39 ` Ian Rogers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230502223851.2234828-24-irogers@google.com \
--to=irogers@google.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=ahmad.yasin@intel.com \
--cc=ak@linux.intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=atrajeev@linux.vnet.ibm.com \
--cc=caleb.biggers@intel.com \
--cc=edward.baker@intel.com \
--cc=eranian@google.com \
--cc=florian.fischer@muhq.space \
--cc=james.clark@arm.com \
--cc=john.g.garry@oracle.com \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=kjain@linux.ibm.com \
--cc=leo.yan@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=perry.taylor@intel.com \
--cc=peterz@infradead.org \
--cc=ravi.bangoria@amd.com \
--cc=robh@kernel.org \
--cc=samantha.alt@intel.com \
--cc=sumanthk@linux.ibm.com \
--cc=suzuki.poulose@arm.com \
--cc=tegongkang@gmail.com \
--cc=tmricht@linux.ibm.com \
--cc=weilin.wang@intel.com \
--cc=yangjihong1@huawei.com \
--cc=yangtiezhu@loongson.cn \
--cc=zhengjun.xing@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.