diff options
author | Ian Rogers <irogers@google.com> | 2023-08-24 07:13:25 +0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-08-24 17:08:47 +0300 |
commit | e6ff1eed3584362dcf5ffb6b9daf497183b4d3a8 (patch) | |
tree | 29819cdefc880a4073488fda221e9328cbf4e124 /tools/perf/util/pmu.c | |
parent | 7c52f10c0d4d8db86ef94b40446efbe291d067dc (diff) | |
download | linux-e6ff1eed3584362dcf5ffb6b9daf497183b4d3a8.tar.xz |
perf pmu: Lazily add JSON events
Rather than scanning all JSON events and adding them when a PMU is
created, add the alias when the JSON event is needed.
Average core PMU scanning run time reduced by 60.2%. Average PMU
scanning run time reduced by 15%. Page faults with no events reduced by
74 page faults, 4% of total.
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Gaosheng Cui <cuigaosheng1@huawei.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20230824041330.266337-14-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/pmu.c')
-rw-r--r-- | tools/perf/util/pmu.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 685903c1970b..b6a118226541 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -523,8 +523,9 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, int dirfd, const char *name if (!pe) { /* Update an event from sysfs with json data. */ if (pmu->events_table) { - pmu_events_table__find_event(pmu->events_table, pmu, name, - update_alias, alias); + if (pmu_events_table__find_event(pmu->events_table, pmu, name, + update_alias, alias) == 0) + pmu->loaded_json_aliases++; } } @@ -548,6 +549,10 @@ static int perf_pmu__new_alias(struct perf_pmu *pmu, int dirfd, const char *name "%s=%s", term->config, term->val.str); } alias->str = strdup(newval); + if (!pe) + pmu->sysfs_aliases++; + else + pmu->loaded_json_aliases++; list_add_tail(&alias->list, &pmu->aliases); return 0; } @@ -878,7 +883,11 @@ static void pmu_add_cpu_aliases(struct perf_pmu *pmu) if (!pmu->events_table) return; + if (pmu->cpu_aliases_added) + return; + pmu_add_cpu_aliases_table(pmu, pmu->events_table); + pmu->cpu_aliases_added = true; } static int pmu_add_sys_aliases_iter_fn(const struct pmu_event *pe, @@ -990,7 +999,6 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char pmu->id = pmu_id(name); pmu->max_precise = pmu_max_precise(dirfd, pmu); pmu->events_table = perf_pmu__find_events_table(pmu); - pmu_add_cpu_aliases(pmu); pmu_add_sys_aliases(pmu); list_add_tail(&pmu->list, pmus); @@ -1368,6 +1376,7 @@ int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr, static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, struct parse_events_term *term) { + struct perf_pmu_alias *alias; char *name; if (parse_events__is_hardcoded_term(term)) @@ -1388,7 +1397,18 @@ static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu, return NULL; } - return perf_pmu__find_alias(pmu, name); + alias = perf_pmu__find_alias(pmu, name); + if (alias || pmu->cpu_aliases_added) + return alias; + + /* Alias doesn't exist, try to get it from the json events. */ + if (pmu->events_table && + pmu_events_table__find_event(pmu->events_table, pmu, name, + pmu_add_cpu_aliases_map_callback, + pmu) == 0) { + alias = perf_pmu__find_alias(pmu, name); + } + return alias; } @@ -1555,18 +1575,23 @@ bool perf_pmu__auto_merge_stats(const struct perf_pmu *pmu) return !pmu->is_core || perf_pmus__num_core_pmus() == 1; } -bool perf_pmu__have_event(const struct perf_pmu *pmu, const char *name) +bool perf_pmu__have_event(struct perf_pmu *pmu, const char *name) { - return perf_pmu__find_alias(pmu, name) != NULL; + if (perf_pmu__find_alias(pmu, name) != NULL) + return true; + if (pmu->cpu_aliases_added || !pmu->events_table) + return false; + return pmu_events_table__find_event(pmu->events_table, pmu, name, NULL, NULL) == 0; } -size_t perf_pmu__num_events(const struct perf_pmu *pmu) +size_t perf_pmu__num_events(struct perf_pmu *pmu) { - struct list_head *list; - size_t nr = 0; + size_t nr = pmu->sysfs_aliases; - list_for_each(list, &pmu->aliases) - nr++; + if (pmu->cpu_aliases_added) + nr += pmu->loaded_json_aliases; + else if (pmu->events_table) + nr += pmu_events_table__num_events(pmu->events_table, pmu) - pmu->loaded_json_aliases; return pmu->selectable ? nr + 1 : nr; } @@ -1604,7 +1629,7 @@ static char *format_alias(char *buf, int len, const struct perf_pmu *pmu, return buf; } -int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_event_callback cb) +int perf_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_callback cb) { char buf[1024]; struct perf_pmu_alias *event; @@ -1613,6 +1638,7 @@ int perf_pmu__for_each_event(const struct perf_pmu *pmu, void *state, pmu_event_ }; int ret = 0; + pmu_add_cpu_aliases(pmu); list_for_each_entry(event, &pmu->aliases, list) { size_t buf_used; |