提交 9f21b815 编写于 作者: M Mark Rutland 提交者: Arnaldo Carvalho de Melo

perf evlist: Only open events on CPUs an evsel permits

In systems with heterogeneous CPU PMUs, it's possible for each evsel to
cover a distinct set of CPUs, and hence the cpu_map associated with each
evsel may have a distinct idx<->id mapping. Any of these may be distinct
from the evlist's cpu map.

Events can be tied to the same fd so long as they use the same per-cpu
ringbuffer (i.e. so long as they are on the same CPU). To acquire the
correct FDs, we must compare the Linux logical IDs rather than the evsel
or evlist indices.

This path adds logic to perf_evlist__mmap_per_evsel to handle this,
translating IDs as required. As PMUs may cover a subset of CPUs from the
evlist, we skip the CPUs a PMU cannot handle.

Without this patch, perf record may try to mmap erroneous FDs on
heterogeneous systems, and will bail out early rather than running the
workload.
Signed-off-by: NMark Rutland <mark.rutland@arm.com>
Acked-by: NJiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will.deacon@arm.com>
Link: http://lkml.kernel.org/r/1473330112-28528-7-git-send-email-mark.rutland@arm.comSigned-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
上级 70fbe057
...@@ -1032,16 +1032,18 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused, ...@@ -1032,16 +1032,18 @@ perf_evlist__should_poll(struct perf_evlist *evlist __maybe_unused,
} }
static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
struct mmap_params *mp, int cpu, struct mmap_params *mp, int cpu_idx,
int thread, int *_output, int *_output_backward) int thread, int *_output, int *_output_backward)
{ {
struct perf_evsel *evsel; struct perf_evsel *evsel;
int revent; int revent;
int evlist_cpu = cpu_map__cpu(evlist->cpus, cpu_idx);
evlist__for_each_entry(evlist, evsel) { evlist__for_each_entry(evlist, evsel) {
struct perf_mmap *maps = evlist->mmap; struct perf_mmap *maps = evlist->mmap;
int *output = _output; int *output = _output;
int fd; int fd;
int cpu;
if (evsel->attr.write_backward) { if (evsel->attr.write_backward) {
output = _output_backward; output = _output_backward;
...@@ -1060,6 +1062,10 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, ...@@ -1060,6 +1062,10 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
if (evsel->system_wide && thread) if (evsel->system_wide && thread)
continue; continue;
cpu = cpu_map__idx(evsel->cpus, evlist_cpu);
if (cpu == -1)
continue;
fd = FD(evsel, cpu, thread); fd = FD(evsel, cpu, thread);
if (*output == -1) { if (*output == -1) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册