diff options
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/evlist.c | 67 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 29 | ||||
-rw-r--r-- | tools/perf/util/python.c | 25 |
3 files changed, 86 insertions, 35 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 @@ #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define SID(e, x, y) xyarray__entry(e->id, x, y) -void perf_evlist__init(struct perf_evlist *evlist) +void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, + struct thread_map *threads) { int i; for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) INIT_HLIST_HEAD(&evlist->heads[i]); INIT_LIST_HEAD(&evlist->entries); + perf_evlist__set_maps(evlist, cpus, threads); } -struct perf_evlist *perf_evlist__new(void) +struct perf_evlist *perf_evlist__new(struct cpu_map *cpus, + struct thread_map *threads) { struct perf_evlist *evlist = zalloc(sizeof(*evlist)); if (evlist != NULL) - perf_evlist__init(evlist); + perf_evlist__init(evlist, cpus, threads); return evlist; } @@ -88,9 +91,9 @@ int perf_evlist__add_default(struct perf_evlist *evlist) return 0; } -int perf_evlist__alloc_pollfd(struct perf_evlist *evlist, int ncpus, int nthreads) +int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) { - int nfds = ncpus * nthreads * evlist->nr_entries; + int nfds = evlist->cpus->nr * evlist->threads->nr * evlist->nr_entries; evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); return evlist->pollfd != NULL ? 0 : -ENOMEM; } @@ -213,11 +216,11 @@ union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) return event; } -void perf_evlist__munmap(struct perf_evlist *evlist, int ncpus) +void perf_evlist__munmap(struct perf_evlist *evlist) { int cpu; - for (cpu = 0; cpu < ncpus; cpu++) { + for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { if (evlist->mmap[cpu].base != NULL) { munmap(evlist->mmap[cpu].base, evlist->mmap_len); evlist->mmap[cpu].base = NULL; @@ -225,9 +228,9 @@ void perf_evlist__munmap(struct perf_evlist *evlist, int ncpus) } } -int perf_evlist__alloc_mmap(struct perf_evlist *evlist, int ncpus) +int perf_evlist__alloc_mmap(struct perf_evlist *evlist) { - evlist->mmap = zalloc(ncpus * sizeof(struct perf_mmap)); + evlist->mmap = zalloc(evlist->cpus->nr * sizeof(struct perf_mmap)); return evlist->mmap != NULL ? 0 : -ENOMEM; } @@ -248,8 +251,6 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int cpu, int prot, /** perf_evlist__mmap - Create per cpu maps to receive events * * @evlist - list of events - * @cpus - cpu map being monitored - * @threads - threads map being monitored * @pages - map length in pages * @overwrite - overwrite older events? * @@ -259,21 +260,22 @@ static int __perf_evlist__mmap(struct perf_evlist *evlist, int cpu, int prot, * unsigned int head = perf_mmap__read_head(m); * * perf_mmap__write_tail(m, head) + * + * Using perf_evlist__read_on_cpu does this automatically. */ -int perf_evlist__mmap(struct perf_evlist *evlist, struct cpu_map *cpus, - struct thread_map *threads, int pages, bool overwrite) +int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) { unsigned int page_size = sysconf(_SC_PAGE_SIZE); int mask = pages * page_size - 1, cpu; struct perf_evsel *first_evsel, *evsel; + const struct cpu_map *cpus = evlist->cpus; + const struct thread_map *threads = evlist->threads; int thread, prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); - if (evlist->mmap == NULL && - perf_evlist__alloc_mmap(evlist, cpus->nr) < 0) + if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) return -ENOMEM; - if (evlist->pollfd == NULL && - perf_evlist__alloc_pollfd(evlist, cpus->nr, threads->nr) < 0) + if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0) return -ENOMEM; evlist->overwrite = overwrite; @@ -315,3 +317,34 @@ out_unmap: } return -1; } + +int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, + pid_t target_tid, const char *cpu_list) +{ + evlist->threads = thread_map__new(target_pid, target_tid); + + if (evlist->threads == NULL) + return -1; + + if (target_tid != -1) + evlist->cpus = cpu_map__dummy_new(); + else + evlist->cpus = cpu_map__new(cpu_list); + + if (evlist->cpus == NULL) + goto out_delete_threads; + + return 0; + +out_delete_threads: + thread_map__delete(evlist->threads); + return -1; +} + +void perf_evlist__delete_maps(struct perf_evlist *evlist) +{ + cpu_map__delete(evlist->cpus); + thread_map__delete(evlist->threads); + evlist->cpus = NULL; + evlist->threads = NULL; +} diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 85aca6eba16..c9884056097 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -22,28 +22,43 @@ struct perf_evlist { union perf_event event_copy; struct perf_mmap *mmap; struct pollfd *pollfd; + struct thread_map *threads; + struct cpu_map *cpus; }; struct perf_evsel; -struct perf_evlist *perf_evlist__new(void); -void perf_evlist__init(struct perf_evlist *evlist); +struct perf_evlist *perf_evlist__new(struct cpu_map *cpus, + struct thread_map *threads); +void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, + struct thread_map *threads); void perf_evlist__exit(struct perf_evlist *evlist); void perf_evlist__delete(struct perf_evlist *evlist); void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); int perf_evlist__add_default(struct perf_evlist *evlist); -int perf_evlist__alloc_pollfd(struct perf_evlist *evlist, int ncpus, int nthreads); +int perf_evlist__alloc_pollfd(struct perf_evlist *evlist); void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd); struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); union perf_event *perf_evlist__read_on_cpu(struct perf_evlist *self, int cpu); -int perf_evlist__alloc_mmap(struct perf_evlist *evlist, int ncpus); -int perf_evlist__mmap(struct perf_evlist *evlist, struct cpu_map *cpus, - struct thread_map *threads, int pages, bool overwrite); -void perf_evlist__munmap(struct perf_evlist *evlist, int ncpus); +int perf_evlist__alloc_mmap(struct perf_evlist *evlist); +int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite); +void perf_evlist__munmap(struct perf_evlist *evlist); + +static inline void perf_evlist__set_maps(struct perf_evlist *evlist, + struct cpu_map *cpus, + struct thread_map *threads) +{ + evlist->cpus = cpus; + evlist->threads = threads; +} + +int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, + pid_t target_tid, const char *cpu_list); +void perf_evlist__delete_maps(struct perf_evlist *evlist); #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 88d47895a79..d2d52175362 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -553,7 +553,16 @@ struct pyrf_evlist { static int pyrf_evlist__init(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { - perf_evlist__init(&pevlist->evlist); + PyObject *pcpus = NULL, *pthreads = NULL; + struct cpu_map *cpus; + struct thread_map *threads; + + if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) + return -1; + + threads = ((struct pyrf_thread_map *)pthreads)->threads; + cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; + perf_evlist__init(&pevlist->evlist, cpus, threads); return 0; } @@ -567,21 +576,15 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs) { struct perf_evlist *evlist = &pevlist->evlist; - PyObject *pcpus = NULL, *pthreads = NULL; - struct cpu_map *cpus = NULL; - struct thread_map *threads = NULL; - static char *kwlist[] = {"cpus", "threads", "pages", "overwrite", + static char *kwlist[] = {"pages", "overwrite", NULL, NULL}; int pages = 128, overwrite = false; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|ii", kwlist, - &pcpus, &pthreads, &pages, &overwrite)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, + &pages, &overwrite)) return NULL; - threads = ((struct pyrf_thread_map *)pthreads)->threads; - cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; - - if (perf_evlist__mmap(evlist, cpus, threads, pages, overwrite) < 0) { + if (perf_evlist__mmap(evlist, pages, overwrite) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } |