diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index b46f6e4bff3c..e42626422587 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include "thread_map.h" | 16 | #include "thread_map.h" |
17 | 17 | ||
18 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 18 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
19 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) | ||
19 | 20 | ||
20 | int __perf_evsel__sample_size(u64 sample_type) | 21 | int __perf_evsel__sample_size(u64 sample_type) |
21 | { | 22 | { |
@@ -204,15 +205,16 @@ int __perf_evsel__read(struct perf_evsel *evsel, | |||
204 | } | 205 | } |
205 | 206 | ||
206 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | 207 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
207 | struct thread_map *threads, bool group) | 208 | struct thread_map *threads, bool group, |
209 | struct xyarray *group_fds) | ||
208 | { | 210 | { |
209 | int cpu, thread; | 211 | int cpu, thread; |
210 | unsigned long flags = 0; | 212 | unsigned long flags = 0; |
211 | int pid = -1; | 213 | int pid = -1, err; |
212 | 214 | ||
213 | if (evsel->fd == NULL && | 215 | if (evsel->fd == NULL && |
214 | perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) | 216 | perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) |
215 | return -1; | 217 | return -ENOMEM; |
216 | 218 | ||
217 | if (evsel->cgrp) { | 219 | if (evsel->cgrp) { |
218 | flags = PERF_FLAG_PID_CGROUP; | 220 | flags = PERF_FLAG_PID_CGROUP; |
@@ -220,7 +222,7 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
220 | } | 222 | } |
221 | 223 | ||
222 | for (cpu = 0; cpu < cpus->nr; cpu++) { | 224 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
223 | int group_fd = -1; | 225 | int group_fd = group_fds ? GROUP_FD(group_fds, cpu) : -1; |
224 | 226 | ||
225 | for (thread = 0; thread < threads->nr; thread++) { | 227 | for (thread = 0; thread < threads->nr; thread++) { |
226 | 228 | ||
@@ -231,8 +233,10 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
231 | pid, | 233 | pid, |
232 | cpus->map[cpu], | 234 | cpus->map[cpu], |
233 | group_fd, flags); | 235 | group_fd, flags); |
234 | if (FD(evsel, cpu, thread) < 0) | 236 | if (FD(evsel, cpu, thread) < 0) { |
237 | err = -errno; | ||
235 | goto out_close; | 238 | goto out_close; |
239 | } | ||
236 | 240 | ||
237 | if (group && group_fd == -1) | 241 | if (group && group_fd == -1) |
238 | group_fd = FD(evsel, cpu, thread); | 242 | group_fd = FD(evsel, cpu, thread); |
@@ -249,7 +253,17 @@ out_close: | |||
249 | } | 253 | } |
250 | thread = threads->nr; | 254 | thread = threads->nr; |
251 | } while (--cpu >= 0); | 255 | } while (--cpu >= 0); |
252 | return -1; | 256 | return err; |
257 | } | ||
258 | |||
259 | void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads) | ||
260 | { | ||
261 | if (evsel->fd == NULL) | ||
262 | return; | ||
263 | |||
264 | perf_evsel__close_fd(evsel, ncpus, nthreads); | ||
265 | perf_evsel__free_fd(evsel); | ||
266 | evsel->fd = NULL; | ||
253 | } | 267 | } |
254 | 268 | ||
255 | static struct { | 269 | static struct { |
@@ -269,7 +283,8 @@ static struct { | |||
269 | }; | 283 | }; |
270 | 284 | ||
271 | int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | 285 | int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
272 | struct thread_map *threads, bool group) | 286 | struct thread_map *threads, bool group, |
287 | struct xyarray *group_fd) | ||
273 | { | 288 | { |
274 | if (cpus == NULL) { | 289 | if (cpus == NULL) { |
275 | /* Work around old compiler warnings about strict aliasing */ | 290 | /* Work around old compiler warnings about strict aliasing */ |
@@ -279,19 +294,23 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
279 | if (threads == NULL) | 294 | if (threads == NULL) |
280 | threads = &empty_thread_map.map; | 295 | threads = &empty_thread_map.map; |
281 | 296 | ||
282 | return __perf_evsel__open(evsel, cpus, threads, group); | 297 | return __perf_evsel__open(evsel, cpus, threads, group, group_fd); |
283 | } | 298 | } |
284 | 299 | ||
285 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, | 300 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, |
286 | struct cpu_map *cpus, bool group) | 301 | struct cpu_map *cpus, bool group, |
302 | struct xyarray *group_fd) | ||
287 | { | 303 | { |
288 | return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group); | 304 | return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group, |
305 | group_fd); | ||
289 | } | 306 | } |
290 | 307 | ||
291 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, | 308 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, |
292 | struct thread_map *threads, bool group) | 309 | struct thread_map *threads, bool group, |
310 | struct xyarray *group_fd) | ||
293 | { | 311 | { |
294 | return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group); | 312 | return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group, |
313 | group_fd); | ||
295 | } | 314 | } |
296 | 315 | ||
297 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, | 316 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, |