diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/evlist.c | 15 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 2 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 13 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 8 |
4 files changed, 32 insertions, 6 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4b2538e4f679..68bbd3ea771b 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -79,6 +79,7 @@ void evlist__init(struct evlist *evlist, struct perf_cpu_map *cpus, evlist->ctl_fd.fd = -1; evlist->ctl_fd.ack = -1; evlist->ctl_fd.pos = -1; + evlist->nr_br_cntr = -1; } struct evlist *evlist__new(void) @@ -1264,6 +1265,20 @@ u64 evlist__combined_branch_type(struct evlist *evlist) return branch_type; } +void evlist__update_br_cntr(struct evlist *evlist) +{ + struct evsel *evsel; + int i = 0; + + evlist__for_each_entry(evlist, evsel) { + if (evsel->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) { + evsel->br_cntr_idx = i++; + evsel__leader(evsel)->br_cntr_nr++; + } + } + evlist->nr_br_cntr = i; +} + bool evlist__valid_read_format(struct evlist *evlist) { struct evsel *first = evlist__first(evlist), *pos = first; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index cccc34da5a02..b46f1a320783 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -57,6 +57,7 @@ struct evlist { bool enabled; int id_pos; int is_pos; + int nr_br_cntr; u64 combined_sample_type; enum bkw_mmap_state bkw_mmap_state; struct { @@ -219,6 +220,7 @@ int evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel, u64 __evlist__combined_sample_type(struct evlist *evlist); u64 evlist__combined_sample_type(struct evlist *evlist); u64 evlist__combined_branch_type(struct evlist *evlist); +void evlist__update_br_cntr(struct evlist *evlist); bool evlist__sample_id_all(struct evlist *evlist); u16 evlist__id_hdr_size(struct evlist *evlist); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index f22f402d54cc..38a74d6dde49 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2636,17 +2636,18 @@ u64 evsel__bitfield_swap_branch_flags(u64 value) static inline bool evsel__has_branch_counters(const struct evsel *evsel) { - struct evsel *cur, *leader = evsel__leader(evsel); + struct evsel *leader = evsel__leader(evsel); /* The branch counters feature only supports group */ if (!leader || !evsel->evlist) return false; - evlist__for_each_entry(evsel->evlist, cur) { - if ((leader == evsel__leader(cur)) && - (cur->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS)) - return true; - } + if (evsel->evlist->nr_br_cntr < 0) + evlist__update_br_cntr(evsel->evlist); + + if (leader->br_cntr_nr > 0) + return true; + return false; } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a5da4b03bb1c..a393dae1dc96 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -149,6 +149,14 @@ struct evsel { __u64 synth_sample_type; /* + * Store the branch counter related information. + * br_cntr_idx: The idx of the branch counter event in the evlist + * br_cntr_nr: The number of the branch counter event in the group + * (Only available for the leader event) + */ + int br_cntr_idx; + int br_cntr_nr; + /* * bpf_counter_ops serves two use cases: * 1. perf-stat -b counting events used byBPF programs * 2. perf-stat --use-bpf use BPF programs to aggregate counts |