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 dcd59328bb4..95b21fece2c 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 | } | ||
