From cfab54eab73c970afecf43fe5e2126e20caaf27a Mon Sep 17 00:00:00 2001 From: Jiri Olsa 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 Acked-by: Ian Rogers Cc: Alexander Shishkin Cc: Andi Kleen Cc: Michael Petlan Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lore.kernel.org/lkml/20200602214741.1218986-2-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: hongrongxuan 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 PE_VALUE @@ -76,7 +76,7 @@ static void inc_group_count(struct list_head *list, %type PE_MODIFIER_EVENT %type PE_MODIFIER_BP %type PE_EVENT_NAME -%type PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT +%type PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE %type PE_DRV_CFG_TERM %type value_sym %type 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