diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index a8d8463f8ee5..f61e5dd53f5d 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -239,10 +239,8 @@ bool evsel__is_function_event(struct evsel *evsel) void evsel__init(struct evsel *evsel, struct perf_event_attr *attr, int idx) { - perf_evsel__init(&evsel->core, attr); - evsel->idx = idx; + perf_evsel__init(&evsel->core, attr, idx); evsel->tracking = !idx; - evsel->leader = evsel; evsel->unit = ""; evsel->scale = 1.0; evsel->max_events = ULONG_MAX; @@ -410,7 +408,7 @@ struct evsel *evsel__clone(struct evsel *orig) evsel->cgrp = cgroup__get(orig->cgrp); evsel->tp_format = orig->tp_format; evsel->handler = orig->handler; - evsel->leader = orig->leader; + evsel->core.leader = orig->core.leader; evsel->max_events = orig->max_events; evsel->tool_event = orig->tool_event; @@ -1075,7 +1073,7 @@ void __weak arch_evsel__set_sample_weight(struct evsel *evsel) void evsel__config(struct evsel *evsel, struct record_opts *opts, struct callchain_param *callchain) { - struct evsel *leader = evsel->leader; + struct evsel *leader = evsel__leader(evsel); struct perf_event_attr *attr = &evsel->core.attr; int track = evsel->tracking; bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread; @@ -1582,9 +1580,30 @@ int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale) return 0; } +static int evsel__match_other_cpu(struct evsel *evsel, struct evsel *other, + int cpu) +{ + int cpuid; + + cpuid = perf_cpu_map__cpu(evsel->core.cpus, cpu); + return perf_cpu_map__idx(other->core.cpus, cpuid); +} + +static int evsel__hybrid_group_cpu(struct evsel *evsel, int cpu) +{ + struct evsel *leader = evsel__leader(evsel); + + if ((evsel__is_hybrid(evsel) && !evsel__is_hybrid(leader)) || + (!evsel__is_hybrid(evsel) && evsel__is_hybrid(leader))) { + return evsel__match_other_cpu(evsel, leader, cpu); + } + + return cpu; +} + static int get_group_fd(struct evsel *evsel, int cpu, int thread) { - struct evsel *leader = evsel->leader; + struct evsel *leader = evsel__leader(evsel); int fd; if (evsel__is_group_leader(evsel)) @@ -1596,6 +1615,10 @@ static int get_group_fd(struct evsel *evsel, int cpu, int thread) */ BUG_ON(!leader->core.fd); + cpu = evsel__hybrid_group_cpu(evsel, cpu); + if (cpu == -1) + return -1; + fd = FD(leader, cpu, thread); BUG_ON(fd == -1); @@ -2826,3 +2849,23 @@ bool evsel__is_hybrid(struct evsel *evsel) { return evsel->pmu_name && perf_pmu__is_hybrid(evsel->pmu_name); } + +struct evsel *evsel__leader(struct evsel *evsel) +{ + return container_of(evsel->core.leader, struct evsel, core); +} + +bool evsel__has_leader(struct evsel *evsel, struct evsel *leader) +{ + return evsel->core.leader == &leader->core; +} + +bool evsel__is_leader(struct evsel *evsel) +{ + return evsel__has_leader(evsel, evsel); +} + +void evsel__set_leader(struct evsel *evsel, struct evsel *leader) +{ + evsel->core.leader = &leader->core; +} |