diff options
Diffstat (limited to 'tools/perf/util/evlist.c')
-rw-r--r-- | tools/perf/util/evlist.c | 67 |
1 files changed, 50 insertions, 17 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index dcd59328bb49..95b21fece2ce 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -21,21 +21,24 @@ | |||
21 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 21 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
22 | #define SID(e, x, y) xyarray__entry(e->id, x, y) | 22 | #define SID(e, x, y) xyarray__entry(e->id, x, y) |
23 | 23 | ||
24 | void perf_evlist__init(struct perf_evlist *evlist) | 24 | void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, |
25 | struct thread_map *threads) | ||
25 | { | 26 | { |
26 | int i; | 27 | int i; |
27 | 28 | ||
28 | for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) | 29 | for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) |
29 | INIT_HLIST_HEAD(&evlist->heads[i]); | 30 | INIT_HLIST_HEAD(&evlist->heads[i]); |
30 | INIT_LIST_HEAD(&evlist->entries); | 31 | INIT_LIST_HEAD(&evlist->entries); |
32 | perf_evlist__set_maps(evlist, cpus, threads); | ||
31 | } | 33 | } |
32 | 34 | ||
33 | struct perf_evlist *perf_evlist__new(void) | 35 | struct perf_evlist *perf_evlist__new(struct cpu_map *cpus, |
36 | struct thread_map *threads) | ||
34 | { | 37 | { |
35 | struct perf_evlist *evlist = zalloc(sizeof(*evlist)); | 38 | struct perf_evlist *evlist = zalloc(sizeof(*evlist)); |
36 | 39 | ||
37 | if (evlist != NULL) | 40 | if (evlist != NULL) |
38 | perf_evlist__init(evlist); | 41 | perf_evlist__init(evlist, cpus, threads); |
39 | 42 | ||
40 | return evlist; | 43 | return evlist; |
41 | } | 44 | } |
@@ -88,9 +91,9 @@ int perf_evlist__add_default(struct perf_evlist *evlist) | |||
88 | return 0; | 91 | return 0; |
89 | } | 92 | } |
90 | 93 | ||
91 | int perf_evlist__alloc_pollfd(struct perf_evlist *evlist, int ncpus, int nthreads) | 94 | int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) |
92 | { | 95 | { |
93 | int nfds = ncpus * nthreads * evlist->nr_entries; | 96 | int nfds = evlist->cpus->nr * evlist->threads->nr * evlist->nr_entries; |
94 | evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); | 97 | evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); |
95 | return evlist->pollfd != NULL ? 0 : -ENOMEM; | 98 | return evlist->pollfd != NULL ? 0 : -ENOMEM; |
96 | } | 99 | } |
@@ -213,11 +216,11 @@ union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) | |||
213 | return event; | 216 | return event; |
214 | } | 217 | } |
215 | 218 | ||
216 | void perf_evlist__munmap(struct perf_evlist *evlist, int ncpus) | 219 | void perf_evlist__munmap(struct perf_evlist *evlist) |
217 | { | 220 | { |
218 | int cpu; | 221 | int cpu; |
219 | 222 | ||
220 | for (cpu = 0; cpu < ncpus; cpu++) { | 223 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { |
221 | if (evlist->mmap[cpu].base != NULL) { | 224 | if (evlist->mmap[cpu].base != NULL) { |
222 | munmap(evlist->mmap[cpu].base, evlist->mmap_len); | 225 | munmap(evlist->mmap[cpu].base, evlist->mmap_len); |
223 | evlist->mmap[cpu].base = NULL; | 226 | evlist->mmap[cpu].base = NULL; |
@@ -225,9 +228,9 @@ void perf_evlist__munmap(struct perf_evlist *evlist, int ncpus) | |||
225 | } | 228 | } |
226 | } | 229 | } |
227 | 230 | ||
228 | int perf_evlist__alloc_mmap(struct perf_evlist *evlist, int ncpus) | 231 | int perf_evlist__alloc_mmap(struct perf_evlist *evlist) |
229 | { | 232 | { |
230 | evlist->mmap = zalloc(ncpus * sizeof(struct perf_mmap)); | 233 | evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap)); |
231 | return evlist->mmap != NULL ? 0 : -ENOMEM; | 234 | return evlist->mmap != NULL ? 0 : -ENOMEM; |
232 | } | 235 | } |
233 | 236 | ||
@@ -248,8 +251,6 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int cpu, int prot, | |||
248 | /** perf_evlist__mmap - Create per cpu maps to receive events | 251 | /** perf_evlist__mmap - Create per cpu maps to receive events |
249 | * | 252 | * |
250 | * @evlist - list of events | 253 | * @evlist - list of events |
251 | * @cpus - cpu map being monitored | ||
252 | * @threads - threads map being monitored | ||
253 | * @pages - map length in pages | 254 | * @pages - map length in pages |
254 | * @overwrite - overwrite older events? | 255 | * @overwrite - overwrite older events? |
255 | * | 256 | * |
@@ -259,21 +260,22 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int cpu, int prot, | |||
259 | * unsigned int head = perf_mmap__read_head(m); | 260 | * unsigned int head = perf_mmap__read_head(m); |
260 | * | 261 | * |
261 | * perf_mmap__write_tail(m, head) | 262 | * perf_mmap__write_tail(m, head) |
263 | * | ||
264 | * Using perf_evlist__read_on_cpu does this automatically. | ||
262 | */ | 265 | */ |
263 | int perf_evlist__mmap(struct perf_evlist *evlist, struct cpu_map *cpus, | 266 | int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) |
264 | struct thread_map *threads, int pages, bool overwrite) | ||
265 | { | 267 | { |
266 | unsigned int page_size = sysconf(_SC_PAGE_SIZE); | 268 | unsigned int page_size = sysconf(_SC_PAGE_SIZE); |
267 | int mask = pages * page_size - 1, cpu; | 269 | int mask = pages * page_size - 1, cpu; |
268 | struct perf_evsel *first_evsel, *evsel; | 270 | struct perf_evsel *first_evsel, *evsel; |
271 | const struct cpu_map *cpus = evlist->cpus; | ||
272 | const struct thread_map *threads = evlist->threads; | ||
269 | int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); | 273 | int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); |
270 | 274 | ||
271 | if (evlist->mmap == NULL && | 275 | if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) |
272 | perf_evlist__alloc_mmap(evlist, cpus->nr) < 0) | ||
273 | return -ENOMEM; | 276 | return -ENOMEM; |
274 | 277 | ||
275 | if (evlist->pollfd == NULL && | 278 | if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0) |
276 | perf_evlist__alloc_pollfd(evlist, cpus->nr, threads->nr) < 0) | ||
277 | return -ENOMEM; | 279 | return -ENOMEM; |
278 | 280 | ||
279 | evlist->overwrite = overwrite; | 281 | evlist->overwrite = overwrite; |
@@ -315,3 +317,34 @@ out_unmap: | |||
315 | } | 317 | } |
316 | return -1; | 318 | return -1; |
317 | } | 319 | } |
320 | |||
321 | int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, | ||
322 | pid_t target_tid, const char *cpu_list) | ||
323 | { | ||
324 | evlist->threads = thread_map__new(target_pid, target_tid); | ||
325 | |||
326 | if (evlist->threads == NULL) | ||
327 | return -1; | ||
328 | |||
329 | if (target_tid != -1) | ||
330 | evlist->cpus = cpu_map__dummy_new(); | ||
331 | else | ||
332 | evlist->cpus = cpu_map__new(cpu_list); | ||
333 | |||
334 | if (evlist->cpus == NULL) | ||
335 | goto out_delete_threads; | ||
336 | |||
337 | return 0; | ||
338 | |||
339 | out_delete_threads: | ||
340 | thread_map__delete(evlist->threads); | ||
341 | return -1; | ||
342 | } | ||
343 | |||
344 | void perf_evlist__delete_maps(struct perf_evlist *evlist) | ||
345 | { | ||
346 | cpu_map__delete(evlist->cpus); | ||
347 | thread_map__delete(evlist->threads); | ||
348 | evlist->cpus = NULL; | ||
349 | evlist->threads = NULL; | ||
350 | } | ||