diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 211063eed474..8083d5126fca 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -85,6 +85,8 @@ void perf_evsel__exit(struct perf_evsel *evsel) void perf_evsel__delete(struct perf_evsel *evsel) { perf_evsel__exit(evsel); + close_cgroup(evsel->cgrp); + free(evsel->name); free(evsel); } @@ -163,21 +165,43 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, struct thread_map *threads, bool group, bool inherit) { int cpu, thread; + unsigned long flags = 0; + int pid = -1; if (evsel->fd == NULL && perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) return -1; + if (evsel->cgrp) { + flags = PERF_FLAG_PID_CGROUP; + pid = evsel->cgrp->fd; + } + for (cpu = 0; cpu < cpus->nr; cpu++) { int group_fd = -1; - - evsel->attr.inherit = (cpus->map[cpu] < 0) && inherit; + /* + * Don't allow mmap() of inherited per-task counters. This + * would create a performance issue due to all children writing + * to the same buffer. + * + * FIXME: + * Proper fix is not to pass 'inherit' to perf_evsel__open*, + * but a 'flags' parameter, with 'group' folded there as well, + * then introduce a PERF_O_{MMAP,GROUP,INHERIT} enum, and if + * O_MMAP is set, emit a warning if cpu < 0 and O_INHERIT is + * set. Lets go for the minimal fix first tho. + */ + evsel->attr.inherit = (cpus->map[cpu] >= 0) && inherit; for (thread = 0; thread < threads->nr; thread++) { + + if (!evsel->cgrp) + pid = threads->map[thread]; + FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr, - threads->map[thread], + pid, cpus->map[cpu], - group_fd, 0); + group_fd, flags); if (FD(evsel, cpu, thread) < 0) goto out_close; |