189 lines
6.1 KiB
Diff
189 lines
6.1 KiB
Diff
From cfab54eab73c970afecf43fe5e2126e20caaf27a Mon Sep 17 00:00:00 2001
|
|
From: Jiri Olsa <jolsa@kernel.org>
|
|
Date: Tue, 2 Jun 2020 23:47:29 +0200
|
|
Subject: [PATCH 091/201] perf tools: Add fake pmu support
|
|
|
|
mainline inclusion
|
|
from mainline-v5.9-rc1
|
|
commit 387ad33fe710758a8e1b860819a7452bceb4329a
|
|
category: feature
|
|
bugzilla: https://gitee.com/openeuler/kernel/issues/I8C0CX
|
|
|
|
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=387ad33fe710758a8e1b860819a7452bceb4329a
|
|
|
|
----------------------------------------------------------------------
|
|
|
|
Add a way to create a pmu event without the actual PMU being in place.
|
|
|
|
This way we can test metrics defined for any processor.
|
|
|
|
The interface is to define fake_pmu in struct parse_events_state data.
|
|
It will be used only in tests via special interface function added in
|
|
following changes.
|
|
|
|
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
|
|
Acked-by: Ian Rogers <irogers@google.com>
|
|
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
Cc: Andi Kleen <ak@linux.intel.com>
|
|
Cc: Michael Petlan <mpetlan@redhat.com>
|
|
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
Cc: Stephane Eranian <eranian@google.com>
|
|
Link: http://lore.kernel.org/lkml/20200602214741.1218986-2-jolsa@kernel.org
|
|
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
|
|
Conflicts:
|
|
tools/perf/util/parse-events.c
|
|
tools/perf/util/parse-events.h
|
|
---
|
|
tools/perf/util/parse-events.c | 6 ++---
|
|
tools/perf/util/parse-events.h | 1 +
|
|
tools/perf/util/parse-events.l | 8 +++++--
|
|
tools/perf/util/parse-events.y | 41 ++++++++++++++++++++++++++++++++--
|
|
4 files changed, 49 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
|
|
index 328d133933bf..f3fe4ed4a9ea 100644
|
|
--- a/tools/perf/util/parse-events.c
|
|
+++ b/tools/perf/util/parse-events.c
|
|
@@ -1266,7 +1266,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
|
bool use_uncore_alias;
|
|
LIST_HEAD(config_terms);
|
|
|
|
- pmu = perf_pmu__find(name);
|
|
+ pmu = parse_state->fake_pmu ?: perf_pmu__find(name);
|
|
if (!pmu) {
|
|
if (asprintf(&err->str,
|
|
"Cannot find PMU `%s'. Missing kernel support?",
|
|
@@ -1297,7 +1297,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
|
}
|
|
}
|
|
|
|
- if (perf_pmu__check_alias(pmu, head_config, &info))
|
|
+ if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &info))
|
|
return -EINVAL;
|
|
|
|
/*
|
|
@@ -1310,7 +1310,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
|
|
if (get_config_terms(head_config, &config_terms))
|
|
return -ENOMEM;
|
|
|
|
- if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
|
|
+ if (!parse_state->fake_pmu && perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
|
|
struct perf_evsel_config_term *pos, *tmp;
|
|
|
|
list_for_each_entry_safe(pos, tmp, &config_terms, list) {
|
|
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
|
|
index 28af56c9939f..c78809837f29 100644
|
|
--- a/tools/perf/util/parse-events.h
|
|
+++ b/tools/perf/util/parse-events.h
|
|
@@ -120,6 +120,7 @@ struct parse_events_state {
|
|
struct perf_evlist *evlist;
|
|
struct list_head *terms;
|
|
int stoken;
|
|
+ struct perf_pmu *fake_pmu;
|
|
};
|
|
|
|
void parse_events__shrink_config_terms(void);
|
|
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
|
|
index 1ff9f8805410..83ccfea42e9b 100644
|
|
--- a/tools/perf/util/parse-events.l
|
|
+++ b/tools/perf/util/parse-events.l
|
|
@@ -132,12 +132,16 @@ do { \
|
|
yyless(0); \
|
|
} while (0)
|
|
|
|
-static int pmu_str_check(yyscan_t scanner)
|
|
+static int pmu_str_check(yyscan_t scanner, struct parse_events_state *parse_state)
|
|
{
|
|
YYSTYPE *yylval = parse_events_get_lval(scanner);
|
|
char *text = parse_events_get_text(scanner);
|
|
|
|
yylval->str = strdup(text);
|
|
+
|
|
+ if (parse_state->fake_pmu)
|
|
+ return PE_PMU_EVENT_FAKE;
|
|
+
|
|
switch (perf_pmu__parse_check(text)) {
|
|
case PMU_EVENT_SYMBOL_PREFIX:
|
|
return PE_PMU_EVENT_PRE;
|
|
@@ -372,7 +376,7 @@ r{num_raw_hex} { return raw(yyscanner); }
|
|
{modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); }
|
|
{bpf_object} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_OBJECT); }
|
|
{bpf_source} { if (!isbpf(yyscanner)) { USER_REJECT }; return str(yyscanner, PE_BPF_SOURCE); }
|
|
-{name} { return pmu_str_check(yyscanner); }
|
|
+{name} { return pmu_str_check(yyscanner, _parse_state); }
|
|
{name_tag} { return str(yyscanner, PE_NAME); }
|
|
"/" { BEGIN(config); return '/'; }
|
|
- { return '-'; }
|
|
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
|
|
index ff913778a7d4..f03da974770c 100644
|
|
--- a/tools/perf/util/parse-events.y
|
|
+++ b/tools/perf/util/parse-events.y
|
|
@@ -59,7 +59,7 @@ static void inc_group_count(struct list_head *list,
|
|
%token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
|
|
%token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
|
|
%token PE_ERROR
|
|
-%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
|
|
+%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
|
|
%token PE_ARRAY_ALL PE_ARRAY_RANGE
|
|
%token PE_DRV_CFG_TERM
|
|
%type <num> PE_VALUE
|
|
@@ -76,7 +76,7 @@ static void inc_group_count(struct list_head *list,
|
|
%type <str> PE_MODIFIER_EVENT
|
|
%type <str> PE_MODIFIER_BP
|
|
%type <str> PE_EVENT_NAME
|
|
-%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
|
|
+%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
|
|
%type <str> PE_DRV_CFG_TERM
|
|
%type <num> value_sym
|
|
%type <head> event_config
|
|
@@ -301,6 +301,43 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
|
|
YYABORT;
|
|
$$ = list;
|
|
}
|
|
+|
|
|
+PE_PMU_EVENT_FAKE sep_dc
|
|
+{
|
|
+ struct list_head *list;
|
|
+ int err;
|
|
+
|
|
+ list = alloc_list();
|
|
+ if (!list)
|
|
+ YYABORT;
|
|
+
|
|
+ err = parse_events_add_pmu(_parse_state, list, $1, NULL, false, false);
|
|
+ free($1);
|
|
+ if (err < 0) {
|
|
+ free(list);
|
|
+ YYABORT;
|
|
+ }
|
|
+ $$ = list;
|
|
+}
|
|
+|
|
|
+PE_PMU_EVENT_FAKE opt_pmu_config
|
|
+{
|
|
+ struct list_head *list;
|
|
+ int err;
|
|
+
|
|
+ list = alloc_list();
|
|
+ if (!list)
|
|
+ YYABORT;
|
|
+
|
|
+ err = parse_events_add_pmu(_parse_state, list, $1, $2, false, false);
|
|
+ free($1);
|
|
+ parse_events_terms__delete($2);
|
|
+ if (err < 0) {
|
|
+ free(list);
|
|
+ YYABORT;
|
|
+ }
|
|
+ $$ = list;
|
|
+}
|
|
|
|
value_sym:
|
|
PE_VALUE_SYM_HW
|
|
--
|
|
2.27.0
|
|
|