diff options
author | Ian Rogers <irogers@google.com> | 2023-05-26 21:44:41 +0200 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-05-28 15:16:15 +0200 |
commit | a90cc5a9eeab45eaf9e47740366b8cf98c3aeb83 (patch) | |
tree | 4b21e5968a2168f7b4512a117682afc822163aad /tools/perf/util/evsel.c | |
parent | perf pmu: Remove is_pmu_hybrid (diff) | |
download | linux-a90cc5a9eeab45eaf9e47740366b8cf98c3aeb83.tar.xz linux-a90cc5a9eeab45eaf9e47740366b8cf98c3aeb83.zip |
perf evsel: Don't let evsel__group_pmu_name() traverse unsorted group
Previously the evsel__group_pmu_name would iterate the evsel's group,
however, the list of evsels aren't yet sorted and so the loop may
terminate prematurely. It is also not desirable to iterate the list of
evsels during list_sort as the list may be broken.
Precompute the group_pmu_name for the evsel before sorting, as part of
the computation and only if necessary, iterate the whole list looking
for group members so that being sorted isn't necessary.
Move the group pmu name computation to parse-events.c given the closer
dependency on the behavior of
parse_events__sort_events_and_fix_groups.
Fixes: 7abf0bccaaec7704 ("perf evsel: Add function to compute group PMU name")
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Dmitrii Dolgov <9erthalion6@gmail.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
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: Rob Herring <robh@kernel.org>
Cc: Sandipan Das <sandipan.das@amd.com>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Link: https://lore.kernel.org/r/20230526194442.2355872-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 31 |
1 files changed, 7 insertions, 24 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ec2ce39d66d8..46da3f0bb47e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -291,6 +291,7 @@ void evsel__init(struct evsel *evsel, evsel->per_pkg_mask = NULL; evsel->collect_stat = false; evsel->pmu_name = NULL; + evsel->group_pmu_name = NULL; evsel->skippable = false; } @@ -391,6 +392,11 @@ struct evsel *evsel__clone(struct evsel *orig) if (evsel->pmu_name == NULL) goto out_err; } + if (orig->group_pmu_name) { + evsel->group_pmu_name = strdup(orig->group_pmu_name); + if (evsel->group_pmu_name == NULL) + goto out_err; + } if (orig->filter) { evsel->filter = strdup(orig->filter); if (evsel->filter == NULL) @@ -787,30 +793,6 @@ bool evsel__name_is(struct evsel *evsel, const char *name) return !strcmp(evsel__name(evsel), name); } -const char *evsel__group_pmu_name(const struct evsel *evsel) -{ - struct evsel *leader = evsel__leader(evsel); - struct evsel *pos; - - /* - * Software events may be in a group with other uncore PMU events. Use - * the pmu_name of the first non-software event to avoid breaking the - * software event out of the group. - * - * Aux event leaders, like intel_pt, expect a group with events from - * other PMUs, so substitute the AUX event's PMU in this case. - */ - if (evsel->core.attr.type == PERF_TYPE_SOFTWARE || evsel__is_aux_event(leader)) { - /* Starting with the leader, find the first event with a named PMU. */ - for_each_group_evsel(pos, leader) { - if (pos->pmu_name) - return pos->pmu_name; - } - } - - return evsel->pmu_name ?: "cpu"; -} - const char *evsel__metric_id(const struct evsel *evsel) { if (evsel->metric_id) @@ -1492,6 +1474,7 @@ void evsel__exit(struct evsel *evsel) zfree(&evsel->group_name); zfree(&evsel->name); zfree(&evsel->pmu_name); + zfree(&evsel->group_pmu_name); zfree(&evsel->unit); zfree(&evsel->metric_id); evsel__zero_per_pkg(evsel); |