1e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* 2e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 3e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 4e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Parts came from builtin-{top,stat,record}.c, see those files for further 5e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * copyright notes. 6e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 7e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Released under the GPL v2. (and only v2, not any later version) 8e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 9e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <poll.h> 10e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "cpumap.h" 11e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "thread_map.h" 12e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "evlist.h" 13e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "evsel.h" 14e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "util.h" 15e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 16e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <sys/mman.h> 17e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 18e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* ANDROID_CHANGE_BEGIN */ 19e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#if 0 20e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <linux/bitops.h> 21e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include <linux/hash.h> 22e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#else 23e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "include/linux/bitops.h" 24e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#include "include/linux/hash.h" 25e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#endif 26e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/* ANDROID_CHANGE_END */ 27e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 28e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 29e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng#define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 30e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 31e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, 32e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread_map *threads) 33e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 34e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int i; 35e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 36e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) 37e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng INIT_HLIST_HEAD(&evlist->heads[i]); 38e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng INIT_LIST_HEAD(&evlist->entries); 39e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__set_maps(evlist, cpus, threads); 40e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 41e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 42e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct perf_evlist *perf_evlist__new(struct cpu_map *cpus, 43e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct thread_map *threads) 44e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 45e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evlist *evlist = zalloc(sizeof(*evlist)); 46e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 47e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist != NULL) 48e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__init(evlist, cpus, threads); 49e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 50e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return evlist; 51e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 52e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 53e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void perf_evlist__purge(struct perf_evlist *evlist) 54e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 55e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *pos, *n; 56e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 57e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry_safe(pos, n, &evlist->entries, node) { 58e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_del_init(&pos->node); 59e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evsel__delete(pos); 60e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 61e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 62e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->nr_entries = 0; 63e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 64e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 65e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__exit(struct perf_evlist *evlist) 66e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 67e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng free(evlist->mmap); 68e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng free(evlist->pollfd); 69e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap = NULL; 70e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->pollfd = NULL; 71e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 72e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 73e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__delete(struct perf_evlist *evlist) 74e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 75e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__purge(evlist); 76e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__exit(evlist); 77e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng free(evlist); 78e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 79e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 80e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) 81e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 82e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_add_tail(&entry->node, &evlist->entries); 83e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ++evlist->nr_entries; 84e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 85e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 86e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_evlist__add_default(struct perf_evlist *evlist) 87e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 88e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_event_attr attr = { 89e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .type = PERF_TYPE_HARDWARE, 90e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng .config = PERF_COUNT_HW_CPU_CYCLES, 91e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng }; 92e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel = perf_evsel__new(&attr, 0); 93e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 94e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evsel == NULL) 95e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -ENOMEM; 96e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 97e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__add(evlist, evsel); 98e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 99e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 100e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 101e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_evlist__alloc_pollfd(struct perf_evlist *evlist) 102e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 103e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int nfds = evlist->cpus->nr * evlist->threads->nr * evlist->nr_entries; 104e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); 105e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return evlist->pollfd != NULL ? 0 : -ENOMEM; 106e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 107e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 108e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) 109e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 110e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fcntl(fd, F_SETFL, O_NONBLOCK); 111e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->pollfd[evlist->nr_fds].fd = fd; 112e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->pollfd[evlist->nr_fds].events = POLLIN; 113e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->nr_fds++; 114e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 115e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 116e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic void perf_evlist__id_hash(struct perf_evlist *evlist, 117e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel, 118e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, int thread, u64 id) 119e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 120e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int hash; 121e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_sample_id *sid = SID(evsel, cpu, thread); 122e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 123e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sid->id = id; 124e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng sid->evsel = evsel; 125e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); 126e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng hlist_add_head(&sid->node, &evlist->heads[hash]); 127e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 128e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 129e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, 130e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, int thread, u64 id) 131e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 132e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__id_hash(evlist, evsel, cpu, thread, id); 133e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evsel->id[evsel->ids++] = id; 134e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 135e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 136e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_evlist__id_add_fd(struct perf_evlist *evlist, 137e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel, 138e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, int thread, int fd) 139e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 140e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng u64 read_data[4] = { 0, }; 141e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int id_idx = 1; /* The first entry is the counter value */ 142e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 143e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!(evsel->attr.read_format & PERF_FORMAT_ID) || 144e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng read(fd, &read_data, sizeof(read_data)) == -1) 145e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 146e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 147e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 148e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ++id_idx; 149e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 150e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng ++id_idx; 151e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 152e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__id_add(evlist, evsel, cpu, thread, read_data[id_idx]); 153e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 154e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 155e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 156e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstruct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) 157e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 158e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct hlist_head *head; 159e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct hlist_node *pos; 160e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_sample_id *sid; 161e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int hash; 162e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 163e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->nr_entries == 1) 164e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return list_entry(evlist->entries.next, struct perf_evsel, node); 165e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 166e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 167e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng head = &evlist->heads[hash]; 168e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 169e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng hlist_for_each_entry(sid, pos, head, node) 170e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (sid->id == id) 171e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return sid->evsel; 172e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return NULL; 173e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 174e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 175e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengunion perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) 176e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 177e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* XXX Move this to perf.c, making it generally available */ 178e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int page_size = sysconf(_SC_PAGE_SIZE); 179e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_mmap *md = &evlist->mmap[idx]; 180e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int head = perf_mmap__read_head(md); 181e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int old = md->prev; 182e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned char *data = md->base + page_size; 183e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng union perf_event *event = NULL; 184e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 185e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->overwrite) { 186e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 187e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * If we're further behind than half the buffer, there's a chance 188e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * the writer will bite our tail and mess up the samples under us. 189e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 190e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * If we somehow ended up ahead of the head, we got messed up. 191e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 192e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * In either case, truncate and restart at head. 193e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 194e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int diff = head - old; 195e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (diff > md->mask / 2 || diff < 0) { 196e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); 197e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 198e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 199e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * head points to a known good entry, start there. 200e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 201e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng old = head; 202e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 203e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 204e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 205e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (old != head) { 206e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng size_t size; 207e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 208e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event = (union perf_event *)&data[old & md->mask]; 209e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng size = event->header.size; 210e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 211e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng /* 212e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Event straddles the mmap boundary -- header should always 213e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * be inside due to u64 alignment of output. 214e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 215e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if ((old & md->mask) + size != ((old + size) & md->mask)) { 216e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int offset = old; 217e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int len = min(sizeof(*event), size), cpy; 218e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng void *dst = &evlist->event_copy; 219e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 220e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng do { 221e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpy = min(md->mask + 1 - (offset & md->mask), len); 222e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng memcpy(dst, &data[offset & md->mask], cpy); 223e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng offset += cpy; 224e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng dst += cpy; 225e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng len -= cpy; 226e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } while (len); 227e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 228e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng event = &evlist->event_copy; 229e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 230e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 231e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng old += size; 232e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 233e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 234e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng md->prev = old; 235e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 236e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!evlist->overwrite) 237e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_mmap__write_tail(md, old); 238e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 239e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return event; 240e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 241e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 242e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__munmap(struct perf_evlist *evlist) 243e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 244e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int i; 245e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 246e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (i = 0; i < evlist->nr_mmaps; i++) { 247e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->mmap[i].base != NULL) { 248e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng munmap(evlist->mmap[i].base, evlist->mmap_len); 249e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap[i].base = NULL; 250e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 251e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 252e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 253e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng free(evlist->mmap); 254e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap = NULL; 255e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 256e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 257e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_evlist__alloc_mmap(struct perf_evlist *evlist) 258e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 259e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->nr_mmaps = evlist->cpus->nr; 260e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->cpus->map[0] == -1) 261e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->nr_mmaps = evlist->threads->nr; 262e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 263e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return evlist->mmap != NULL ? 0 : -ENOMEM; 264e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 265e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 266e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int __perf_evlist__mmap(struct perf_evlist *evlist, 267e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int idx, int prot, int mask, int fd) 268e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 269e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap[idx].prev = 0; 270e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap[idx].mask = mask; 271e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, 272e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng MAP_SHARED, fd, 0); 273e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->mmap[idx].base == MAP_FAILED) 274e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 275e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 276e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__add_pollfd(evlist, fd); 277e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 278e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 279e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 280e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask) 281e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 282e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel; 283e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu, thread; 284e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 285e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 286e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int output = -1; 287e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 288e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (thread = 0; thread < evlist->threads->nr; thread++) { 289e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry(evsel, &evlist->entries, node) { 290e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int fd = FD(evsel, cpu, thread); 291e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 292e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (output == -1) { 293e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng output = fd; 294e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (__perf_evlist__mmap(evlist, cpu, 295e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng prot, mask, output) < 0) 296e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out_unmap; 297e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 298e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) 299e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out_unmap; 300e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 301e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 302e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if ((evsel->attr.read_format & PERF_FORMAT_ID) && 303e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) 304e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out_unmap; 305e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 306e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 307e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 308e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 309e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 310e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 311e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengout_unmap: 312e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 313e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->mmap[cpu].base != NULL) { 314e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng munmap(evlist->mmap[cpu].base, evlist->mmap_len); 315e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap[cpu].base = NULL; 316e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 317e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 318e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 319e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 320e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 321e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengstatic int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask) 322e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 323e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel; 324e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int thread; 325e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 326e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (thread = 0; thread < evlist->threads->nr; thread++) { 327e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int output = -1; 328e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 329e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry(evsel, &evlist->entries, node) { 330e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int fd = FD(evsel, 0, thread); 331e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 332e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (output == -1) { 333e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng output = fd; 334e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (__perf_evlist__mmap(evlist, thread, 335e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng prot, mask, output) < 0) 336e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out_unmap; 337e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } else { 338e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) 339e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out_unmap; 340e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 341e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 342e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if ((evsel->attr.read_format & PERF_FORMAT_ID) && 343e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0) 344e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out_unmap; 345e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 346e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 347e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 348e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 349e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 350e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengout_unmap: 351e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (thread = 0; thread < evlist->threads->nr; thread++) { 352e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->mmap[thread].base != NULL) { 353e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng munmap(evlist->mmap[thread].base, evlist->mmap_len); 354e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap[thread].base = NULL; 355e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 356e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 357e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 358e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 359e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 360e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng/** perf_evlist__mmap - Create per cpu maps to receive events 361e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 362e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * @evlist - list of events 363e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * @pages - map length in pages 364e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * @overwrite - overwrite older events? 365e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 366e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * If overwrite is false the user needs to signal event consuption using: 367e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 368e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * struct perf_mmap *m = &evlist->mmap[cpu]; 369e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * unsigned int head = perf_mmap__read_head(m); 370e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 371e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * perf_mmap__write_tail(m, head) 372e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * 373e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng * Using perf_evlist__read_on_cpu does this automatically. 374e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng */ 375e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) 376e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 377e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng unsigned int page_size = sysconf(_SC_PAGE_SIZE); 378e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int mask = pages * page_size - 1; 379e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel; 380e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const struct cpu_map *cpus = evlist->cpus; 381e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const struct thread_map *threads = evlist->threads; 382e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 383e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 384e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 385e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -ENOMEM; 386e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 387e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 388e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -ENOMEM; 389e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 390e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->overwrite = overwrite; 391e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->mmap_len = (pages + 1) * page_size; 392e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 393e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry(evsel, &evlist->entries, node) { 394e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if ((evsel->attr.read_format & PERF_FORMAT_ID) && 395e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evsel->sample_id == NULL && 396e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) 397e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -ENOMEM; 398e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 399e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 400e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->cpus->map[0] == -1) 401e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return perf_evlist__mmap_per_thread(evlist, prot, mask); 402e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 403e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return perf_evlist__mmap_per_cpu(evlist, prot, mask); 404e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 405e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 406e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, 407e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pid_t target_tid, const char *cpu_list) 408e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 409e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->threads = thread_map__new(target_pid, target_tid); 410e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 411e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->threads == NULL) 412e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 413e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 414e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (cpu_list == NULL && target_tid != -1) 415e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->cpus = cpu_map__dummy_new(); 416e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng else 417e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->cpus = cpu_map__new(cpu_list); 418e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 419e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (evlist->cpus == NULL) 420e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng goto out_delete_threads; 421e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 422e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 423e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 424e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengout_delete_threads: 425e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_map__delete(evlist->threads); 426e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return -1; 427e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 428e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 429e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengvoid perf_evlist__delete_maps(struct perf_evlist *evlist) 430e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 431e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng cpu_map__delete(evlist->cpus); 432e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng thread_map__delete(evlist->threads); 433e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->cpus = NULL; 434e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng evlist->threads = NULL; 435e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 436e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 437e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengint perf_evlist__set_filters(struct perf_evlist *evlist) 438e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 439e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const struct thread_map *threads = evlist->threads; 440e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng const struct cpu_map *cpus = evlist->cpus; 441e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *evsel; 442e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng char *filter; 443e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int thread; 444e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int cpu; 445e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int err; 446e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng int fd; 447e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 448e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry(evsel, &evlist->entries, node) { 449e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng filter = evsel->filter; 450e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (!filter) 451e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng continue; 452e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (cpu = 0; cpu < cpus->nr; cpu++) { 453e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng for (thread = 0; thread < threads->nr; thread++) { 454e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng fd = FD(evsel, cpu, thread); 455e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng err = ioctl(fd, PERF_EVENT_IOC_SET_FILTER, filter); 456e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (err) 457e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return err; 458e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 459e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 460e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 461e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 462e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return 0; 463e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 464e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 465e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengbool perf_evlist__valid_sample_type(const struct perf_evlist *evlist) 466e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 467e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *pos, *first; 468e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 469e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); 470e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 471e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry_continue(pos, &evlist->entries, node) { 472e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (first->attr.sample_type != pos->attr.sample_type) 473e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return false; 474e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 475e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 476e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return true; 477e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 478e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 479e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengu64 perf_evlist__sample_type(const struct perf_evlist *evlist) 480e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 481e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *first; 482e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 483e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng first = list_entry(evlist->entries.next, struct perf_evsel, node); 484e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return first->attr.sample_type; 485e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 486e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 487e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengbool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist) 488e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 489e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *pos, *first; 490e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 491e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); 492e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 493e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng list_for_each_entry_continue(pos, &evlist->entries, node) { 494e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng if (first->attr.sample_id_all != pos->attr.sample_id_all) 495e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return false; 496e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng } 497e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 498e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return true; 499e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 500e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 501e6817ec1d8ab31fc7b01906e305f848542df6413Ben Chengbool perf_evlist__sample_id_all(const struct perf_evlist *evlist) 502e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng{ 503e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng struct perf_evsel *first; 504e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng 505e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng first = list_entry(evlist->entries.next, struct perf_evsel, node); 506e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng return first->attr.sample_id_all; 507e6817ec1d8ab31fc7b01906e305f848542df6413Ben Cheng} 508