Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme (at) redhat.com>
      3  *
      4  * Parts came from builtin-{top,stat,record}.c, see those files for further
      5  * copyright notes.
      6  *
      7  * Released under the GPL v2. (and only v2, not any later version)
      8  */
      9 #include "util.h"
     10 #include <lk/debugfs.h>
     11 #include <poll.h>
     12 #include "cpumap.h"
     13 #include "thread_map.h"
     14 #include "target.h"
     15 #include "evlist.h"
     16 #include "evsel.h"
     17 #include "debug.h"
     18 #include <unistd.h>
     19 
     20 #include "parse-events.h"
     21 
     22 #include <sys/mman.h>
     23 
     24 #include <linux/bitops.h>
     25 #include <linux/hash.h>
     26 
     27 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
     28 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
     29 
     30 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
     31 		       struct thread_map *threads)
     32 {
     33 	int i;
     34 
     35 	for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
     36 		INIT_HLIST_HEAD(&evlist->heads[i]);
     37 	INIT_LIST_HEAD(&evlist->entries);
     38 	perf_evlist__set_maps(evlist, cpus, threads);
     39 	evlist->workload.pid = -1;
     40 }
     41 
     42 struct perf_evlist *perf_evlist__new(void)
     43 {
     44 	struct perf_evlist *evlist = zalloc(sizeof(*evlist));
     45 
     46 	if (evlist != NULL)
     47 		perf_evlist__init(evlist, NULL, NULL);
     48 
     49 	return evlist;
     50 }
     51 
     52 /**
     53  * perf_evlist__set_id_pos - set the positions of event ids.
     54  * @evlist: selected event list
     55  *
     56  * Events with compatible sample types all have the same id_pos
     57  * and is_pos.  For convenience, put a copy on evlist.
     58  */
     59 void perf_evlist__set_id_pos(struct perf_evlist *evlist)
     60 {
     61 	struct perf_evsel *first = perf_evlist__first(evlist);
     62 
     63 	evlist->id_pos = first->id_pos;
     64 	evlist->is_pos = first->is_pos;
     65 }
     66 
     67 static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
     68 {
     69 	struct perf_evsel *evsel;
     70 
     71 	list_for_each_entry(evsel, &evlist->entries, node)
     72 		perf_evsel__calc_id_pos(evsel);
     73 
     74 	perf_evlist__set_id_pos(evlist);
     75 }
     76 
     77 static void perf_evlist__purge(struct perf_evlist *evlist)
     78 {
     79 	struct perf_evsel *pos, *n;
     80 
     81 	list_for_each_entry_safe(pos, n, &evlist->entries, node) {
     82 		list_del_init(&pos->node);
     83 		perf_evsel__delete(pos);
     84 	}
     85 
     86 	evlist->nr_entries = 0;
     87 }
     88 
     89 void perf_evlist__exit(struct perf_evlist *evlist)
     90 {
     91 	free(evlist->mmap);
     92 	free(evlist->pollfd);
     93 	evlist->mmap = NULL;
     94 	evlist->pollfd = NULL;
     95 }
     96 
     97 void perf_evlist__delete(struct perf_evlist *evlist)
     98 {
     99 	perf_evlist__purge(evlist);
    100 	perf_evlist__exit(evlist);
    101 	free(evlist);
    102 }
    103 
    104 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
    105 {
    106 	list_add_tail(&entry->node, &evlist->entries);
    107 	if (!evlist->nr_entries++)
    108 		perf_evlist__set_id_pos(evlist);
    109 }
    110 
    111 void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
    112 				   struct list_head *list,
    113 				   int nr_entries)
    114 {
    115 	bool set_id_pos = !evlist->nr_entries;
    116 
    117 	list_splice_tail(list, &evlist->entries);
    118 	evlist->nr_entries += nr_entries;
    119 	if (set_id_pos)
    120 		perf_evlist__set_id_pos(evlist);
    121 }
    122 
    123 void __perf_evlist__set_leader(struct list_head *list)
    124 {
    125 	struct perf_evsel *evsel, *leader;
    126 
    127 	leader = list_entry(list->next, struct perf_evsel, node);
    128 	evsel = list_entry(list->prev, struct perf_evsel, node);
    129 
    130 	leader->nr_members = evsel->idx - leader->idx + 1;
    131 
    132 	list_for_each_entry(evsel, list, node) {
    133 		evsel->leader = leader;
    134 	}
    135 }
    136 
    137 void perf_evlist__set_leader(struct perf_evlist *evlist)
    138 {
    139 	if (evlist->nr_entries) {
    140 		evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0;
    141 		__perf_evlist__set_leader(&evlist->entries);
    142 	}
    143 }
    144 
    145 int perf_evlist__add_default(struct perf_evlist *evlist)
    146 {
    147 	struct perf_event_attr attr = {
    148 		.type = PERF_TYPE_HARDWARE,
    149 		.config = PERF_COUNT_HW_CPU_CYCLES,
    150 	};
    151 	struct perf_evsel *evsel;
    152 
    153 	event_attr_init(&attr);
    154 
    155 	evsel = perf_evsel__new(&attr, 0);
    156 	if (evsel == NULL)
    157 		goto error;
    158 
    159 	/* use strdup() because free(evsel) assumes name is allocated */
    160 	evsel->name = strdup("cycles");
    161 	if (!evsel->name)
    162 		goto error_free;
    163 
    164 	perf_evlist__add(evlist, evsel);
    165 	return 0;
    166 error_free:
    167 	perf_evsel__delete(evsel);
    168 error:
    169 	return -ENOMEM;
    170 }
    171 
    172 static int perf_evlist__add_attrs(struct perf_evlist *evlist,
    173 				  struct perf_event_attr *attrs, size_t nr_attrs)
    174 {
    175 	struct perf_evsel *evsel, *n;
    176 	LIST_HEAD(head);
    177 	size_t i;
    178 
    179 	for (i = 0; i < nr_attrs; i++) {
    180 		evsel = perf_evsel__new(attrs + i, evlist->nr_entries + i);
    181 		if (evsel == NULL)
    182 			goto out_delete_partial_list;
    183 		list_add_tail(&evsel->node, &head);
    184 	}
    185 
    186 	perf_evlist__splice_list_tail(evlist, &head, nr_attrs);
    187 
    188 	return 0;
    189 
    190 out_delete_partial_list:
    191 	list_for_each_entry_safe(evsel, n, &head, node)
    192 		perf_evsel__delete(evsel);
    193 	return -1;
    194 }
    195 
    196 int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
    197 				     struct perf_event_attr *attrs, size_t nr_attrs)
    198 {
    199 	size_t i;
    200 
    201 	for (i = 0; i < nr_attrs; i++)
    202 		event_attr_init(attrs + i);
    203 
    204 	return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
    205 }
    206 
    207 struct perf_evsel *
    208 perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
    209 {
    210 	struct perf_evsel *evsel;
    211 
    212 	list_for_each_entry(evsel, &evlist->entries, node) {
    213 		if (evsel->attr.type   == PERF_TYPE_TRACEPOINT &&
    214 		    (int)evsel->attr.config == id)
    215 			return evsel;
    216 	}
    217 
    218 	return NULL;
    219 }
    220 
    221 struct perf_evsel *
    222 perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
    223 				     const char *name)
    224 {
    225 	struct perf_evsel *evsel;
    226 
    227 	list_for_each_entry(evsel, &evlist->entries, node) {
    228 		if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
    229 		    (strcmp(evsel->name, name) == 0))
    230 			return evsel;
    231 	}
    232 
    233 	return NULL;
    234 }
    235 
    236 int perf_evlist__add_newtp(struct perf_evlist *evlist,
    237 			   const char *sys, const char *name, void *handler)
    238 {
    239 	struct perf_evsel *evsel;
    240 
    241 	evsel = perf_evsel__newtp(sys, name, evlist->nr_entries);
    242 	if (evsel == NULL)
    243 		return -1;
    244 
    245 	evsel->handler.func = handler;
    246 	perf_evlist__add(evlist, evsel);
    247 	return 0;
    248 }
    249 
    250 void perf_evlist__disable(struct perf_evlist *evlist)
    251 {
    252 	int cpu, thread;
    253 	struct perf_evsel *pos;
    254 	int nr_cpus = cpu_map__nr(evlist->cpus);
    255 	int nr_threads = thread_map__nr(evlist->threads);
    256 
    257 	for (cpu = 0; cpu < nr_cpus; cpu++) {
    258 		list_for_each_entry(pos, &evlist->entries, node) {
    259 			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
    260 				continue;
    261 			for (thread = 0; thread < nr_threads; thread++)
    262 				ioctl(FD(pos, cpu, thread),
    263 				      PERF_EVENT_IOC_DISABLE, 0);
    264 		}
    265 	}
    266 }
    267 
    268 void perf_evlist__enable(struct perf_evlist *evlist)
    269 {
    270 	int cpu, thread;
    271 	struct perf_evsel *pos;
    272 	int nr_cpus = cpu_map__nr(evlist->cpus);
    273 	int nr_threads = thread_map__nr(evlist->threads);
    274 
    275 	for (cpu = 0; cpu < nr_cpus; cpu++) {
    276 		list_for_each_entry(pos, &evlist->entries, node) {
    277 			if (!perf_evsel__is_group_leader(pos) || !pos->fd)
    278 				continue;
    279 			for (thread = 0; thread < nr_threads; thread++)
    280 				ioctl(FD(pos, cpu, thread),
    281 				      PERF_EVENT_IOC_ENABLE, 0);
    282 		}
    283 	}
    284 }
    285 
    286 int perf_evlist__disable_event(struct perf_evlist *evlist,
    287 			       struct perf_evsel *evsel)
    288 {
    289 	int cpu, thread, err;
    290 
    291 	if (!evsel->fd)
    292 		return 0;
    293 
    294 	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
    295 		for (thread = 0; thread < evlist->threads->nr; thread++) {
    296 			err = ioctl(FD(evsel, cpu, thread),
    297 				    PERF_EVENT_IOC_DISABLE, 0);
    298 			if (err)
    299 				return err;
    300 		}
    301 	}
    302 	return 0;
    303 }
    304 
    305 int perf_evlist__enable_event(struct perf_evlist *evlist,
    306 			      struct perf_evsel *evsel)
    307 {
    308 	int cpu, thread, err;
    309 
    310 	if (!evsel->fd)
    311 		return -EINVAL;
    312 
    313 	for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
    314 		for (thread = 0; thread < evlist->threads->nr; thread++) {
    315 			err = ioctl(FD(evsel, cpu, thread),
    316 				    PERF_EVENT_IOC_ENABLE, 0);
    317 			if (err)
    318 				return err;
    319 		}
    320 	}
    321 	return 0;
    322 }
    323 
    324 static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
    325 {
    326 	int nr_cpus = cpu_map__nr(evlist->cpus);
    327 	int nr_threads = thread_map__nr(evlist->threads);
    328 	int nfds = nr_cpus * nr_threads * evlist->nr_entries;
    329 	evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
    330 	return evlist->pollfd != NULL ? 0 : -ENOMEM;
    331 }
    332 
    333 void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
    334 {
    335 	fcntl(fd, F_SETFL, O_NONBLOCK);
    336 	evlist->pollfd[evlist->nr_fds].fd = fd;
    337 	evlist->pollfd[evlist->nr_fds].events = POLLIN;
    338 	evlist->nr_fds++;
    339 }
    340 
    341 static void perf_evlist__id_hash(struct perf_evlist *evlist,
    342 				 struct perf_evsel *evsel,
    343 				 int cpu, int thread, u64 id)
    344 {
    345 	int hash;
    346 	struct perf_sample_id *sid = SID(evsel, cpu, thread);
    347 
    348 	sid->id = id;
    349 	sid->evsel = evsel;
    350 	hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
    351 	hlist_add_head(&sid->node, &evlist->heads[hash]);
    352 }
    353 
    354 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
    355 			 int cpu, int thread, u64 id)
    356 {
    357 	perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
    358 	evsel->id[evsel->ids++] = id;
    359 }
    360 
    361 static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
    362 				  struct perf_evsel *evsel,
    363 				  int cpu, int thread, int fd)
    364 {
    365 	u64 read_data[4] = { 0, };
    366 	int id_idx = 1; /* The first entry is the counter value */
    367 	u64 id;
    368 	int ret;
    369 
    370 	ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
    371 	if (!ret)
    372 		goto add;
    373 
    374 	if (errno != ENOTTY)
    375 		return -1;
    376 
    377 	/* Legacy way to get event id.. All hail to old kernels! */
    378 
    379 	/*
    380 	 * This way does not work with group format read, so bail
    381 	 * out in that case.
    382 	 */
    383 	if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
    384 		return -1;
    385 
    386 	if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
    387 	    read(fd, &read_data, sizeof(read_data)) == -1)
    388 		return -1;
    389 
    390 	if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
    391 		++id_idx;
    392 	if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
    393 		++id_idx;
    394 
    395 	id = read_data[id_idx];
    396 
    397  add:
    398 	perf_evlist__id_add(evlist, evsel, cpu, thread, id);
    399 	return 0;
    400 }
    401 
    402 struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id)
    403 {
    404 	struct hlist_head *head;
    405 	struct perf_sample_id *sid;
    406 	int hash;
    407 
    408 	hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
    409 	head = &evlist->heads[hash];
    410 
    411 	hlist_for_each_entry(sid, head, node)
    412 		if (sid->id == id)
    413 			return sid;
    414 
    415 	return NULL;
    416 }
    417 
    418 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
    419 {
    420 	struct perf_sample_id *sid;
    421 
    422 	if (evlist->nr_entries == 1)
    423 		return perf_evlist__first(evlist);
    424 
    425 	sid = perf_evlist__id2sid(evlist, id);
    426 	if (sid)
    427 		return sid->evsel;
    428 
    429 	if (!perf_evlist__sample_id_all(evlist))
    430 		return perf_evlist__first(evlist);
    431 
    432 	return NULL;
    433 }
    434 
    435 static int perf_evlist__event2id(struct perf_evlist *evlist,
    436 				 union perf_event *event, u64 *id)
    437 {
    438 	const u64 *array = event->sample.array;
    439 	ssize_t n;
    440 
    441 	n = (event->header.size - sizeof(event->header)) >> 3;
    442 
    443 	if (event->header.type == PERF_RECORD_SAMPLE) {
    444 		if (evlist->id_pos >= n)
    445 			return -1;
    446 		*id = array[evlist->id_pos];
    447 	} else {
    448 		if (evlist->is_pos > n)
    449 			return -1;
    450 		n -= evlist->is_pos;
    451 		*id = array[n];
    452 	}
    453 	return 0;
    454 }
    455 
    456 static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
    457 						   union perf_event *event)
    458 {
    459 	struct perf_evsel *first = perf_evlist__first(evlist);
    460 	struct hlist_head *head;
    461 	struct perf_sample_id *sid;
    462 	int hash;
    463 	u64 id;
    464 
    465 	if (evlist->nr_entries == 1)
    466 		return first;
    467 
    468 	if (!first->attr.sample_id_all &&
    469 	    event->header.type != PERF_RECORD_SAMPLE)
    470 		return first;
    471 
    472 	if (perf_evlist__event2id(evlist, event, &id))
    473 		return NULL;
    474 
    475 	/* Synthesized events have an id of zero */
    476 	if (!id)
    477 		return first;
    478 
    479 	hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
    480 	head = &evlist->heads[hash];
    481 
    482 	hlist_for_each_entry(sid, head, node) {
    483 		if (sid->id == id)
    484 			return sid->evsel;
    485 	}
    486 	return NULL;
    487 }
    488 
    489 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
    490 {
    491 	struct perf_mmap *md = &evlist->mmap[idx];
    492 	unsigned int head = perf_mmap__read_head(md);
    493 	unsigned int old = md->prev;
    494 	unsigned char *data = md->base + page_size;
    495 	union perf_event *event = NULL;
    496 
    497 	if (evlist->overwrite) {
    498 		/*
    499 		 * If we're further behind than half the buffer, there's a chance
    500 		 * the writer will bite our tail and mess up the samples under us.
    501 		 *
    502 		 * If we somehow ended up ahead of the head, we got messed up.
    503 		 *
    504 		 * In either case, truncate and restart at head.
    505 		 */
    506 		int diff = head - old;
    507 		if (diff > md->mask / 2 || diff < 0) {
    508 			fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
    509 
    510 			/*
    511 			 * head points to a known good entry, start there.
    512 			 */
    513 			old = head;
    514 		}
    515 	}
    516 
    517 	if (old != head) {
    518 		size_t size;
    519 
    520 		event = (union perf_event *)&data[old & md->mask];
    521 		size = event->header.size;
    522 
    523 		/*
    524 		 * Event straddles the mmap boundary -- header should always
    525 		 * be inside due to u64 alignment of output.
    526 		 */
    527 		if ((old & md->mask) + size != ((old + size) & md->mask)) {
    528 			unsigned int offset = old;
    529 			unsigned int len = min(sizeof(*event), size), cpy;
    530 			void *dst = &md->event_copy;
    531 
    532 			do {
    533 				cpy = min(md->mask + 1 - (offset & md->mask), len);
    534 				memcpy(dst, &data[offset & md->mask], cpy);
    535 				offset += cpy;
    536 				dst += cpy;
    537 				len -= cpy;
    538 			} while (len);
    539 
    540 			event = &md->event_copy;
    541 		}
    542 
    543 		old += size;
    544 	}
    545 
    546 	md->prev = old;
    547 
    548 	return event;
    549 }
    550 
    551 void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
    552 {
    553 	if (!evlist->overwrite) {
    554 		struct perf_mmap *md = &evlist->mmap[idx];
    555 		unsigned int old = md->prev;
    556 
    557 		perf_mmap__write_tail(md, old);
    558 	}
    559 }
    560 
    561 static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
    562 {
    563 	if (evlist->mmap[idx].base != NULL) {
    564 		munmap(evlist->mmap[idx].base, evlist->mmap_len);
    565 		evlist->mmap[idx].base = NULL;
    566 	}
    567 }
    568 
    569 void perf_evlist__munmap(struct perf_evlist *evlist)
    570 {
    571 	int i;
    572 
    573 	for (i = 0; i < evlist->nr_mmaps; i++)
    574 		__perf_evlist__munmap(evlist, i);
    575 
    576 	free(evlist->mmap);
    577 	evlist->mmap = NULL;
    578 }
    579 
    580 static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
    581 {
    582 	evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
    583 	if (cpu_map__empty(evlist->cpus))
    584 		evlist->nr_mmaps = thread_map__nr(evlist->threads);
    585 	evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
    586 	return evlist->mmap != NULL ? 0 : -ENOMEM;
    587 }
    588 
    589 static int __perf_evlist__mmap(struct perf_evlist *evlist,
    590 			       int idx, int prot, int mask, int fd)
    591 {
    592 	evlist->mmap[idx].prev = 0;
    593 	evlist->mmap[idx].mask = mask;
    594 	evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
    595 				      MAP_SHARED, fd, 0);
    596 	if (evlist->mmap[idx].base == MAP_FAILED) {
    597 		evlist->mmap[idx].base = NULL;
    598 		return -1;
    599 	}
    600 
    601 	perf_evlist__add_pollfd(evlist, fd);
    602 	return 0;
    603 }
    604 
    605 static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
    606 {
    607 	struct perf_evsel *evsel;
    608 	int cpu, thread;
    609 	int nr_cpus = cpu_map__nr(evlist->cpus);
    610 	int nr_threads = thread_map__nr(evlist->threads);
    611 
    612 	pr_debug2("perf event ring buffer mmapped per cpu\n");
    613 	for (cpu = 0; cpu < nr_cpus; cpu++) {
    614 		int output = -1;
    615 
    616 		for (thread = 0; thread < nr_threads; thread++) {
    617 			list_for_each_entry(evsel, &evlist->entries, node) {
    618 				int fd = FD(evsel, cpu, thread);
    619 
    620 				if (output == -1) {
    621 					output = fd;
    622 					if (__perf_evlist__mmap(evlist, cpu,
    623 								prot, mask, output) < 0)
    624 						goto out_unmap;
    625 				} else {
    626 					if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
    627 						goto out_unmap;
    628 				}
    629 
    630 				if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
    631 				    perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
    632 					goto out_unmap;
    633 			}
    634 		}
    635 	}
    636 
    637 	return 0;
    638 
    639 out_unmap:
    640 	for (cpu = 0; cpu < nr_cpus; cpu++)
    641 		__perf_evlist__munmap(evlist, cpu);
    642 	return -1;
    643 }
    644 
    645 static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
    646 {
    647 	struct perf_evsel *evsel;
    648 	int thread;
    649 	int nr_threads = thread_map__nr(evlist->threads);
    650 
    651 	pr_debug2("perf event ring buffer mmapped per thread\n");
    652 	for (thread = 0; thread < nr_threads; thread++) {
    653 		int output = -1;
    654 
    655 		list_for_each_entry(evsel, &evlist->entries, node) {
    656 			int fd = FD(evsel, 0, thread);
    657 
    658 			if (output == -1) {
    659 				output = fd;
    660 				if (__perf_evlist__mmap(evlist, thread,
    661 							prot, mask, output) < 0)
    662 					goto out_unmap;
    663 			} else {
    664 				if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
    665 					goto out_unmap;
    666 			}
    667 
    668 			if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
    669 			    perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
    670 				goto out_unmap;
    671 		}
    672 	}
    673 
    674 	return 0;
    675 
    676 out_unmap:
    677 	for (thread = 0; thread < nr_threads; thread++)
    678 		__perf_evlist__munmap(evlist, thread);
    679 	return -1;
    680 }
    681 
    682 /** perf_evlist__mmap - Create per cpu maps to receive events
    683  *
    684  * @evlist - list of events
    685  * @pages - map length in pages
    686  * @overwrite - overwrite older events?
    687  *
    688  * If overwrite is false the user needs to signal event consuption using:
    689  *
    690  *	struct perf_mmap *m = &evlist->mmap[cpu];
    691  *	unsigned int head = perf_mmap__read_head(m);
    692  *
    693  *	perf_mmap__write_tail(m, head)
    694  *
    695  * Using perf_evlist__read_on_cpu does this automatically.
    696  */
    697 int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
    698 		      bool overwrite)
    699 {
    700 	struct perf_evsel *evsel;
    701 	const struct cpu_map *cpus = evlist->cpus;
    702 	const struct thread_map *threads = evlist->threads;
    703 	int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), mask;
    704 
    705         /* 512 kiB: default amount of unprivileged mlocked memory */
    706         if (pages == UINT_MAX)
    707                 pages = (512 * 1024) / page_size;
    708 	else if (!is_power_of_2(pages))
    709 		return -EINVAL;
    710 
    711 	mask = pages * page_size - 1;
    712 
    713 	if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
    714 		return -ENOMEM;
    715 
    716 	if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
    717 		return -ENOMEM;
    718 
    719 	evlist->overwrite = overwrite;
    720 	evlist->mmap_len = (pages + 1) * page_size;
    721 
    722 	list_for_each_entry(evsel, &evlist->entries, node) {
    723 		if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
    724 		    evsel->sample_id == NULL &&
    725 		    perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
    726 			return -ENOMEM;
    727 	}
    728 
    729 	if (cpu_map__empty(cpus))
    730 		return perf_evlist__mmap_per_thread(evlist, prot, mask);
    731 
    732 	return perf_evlist__mmap_per_cpu(evlist, prot, mask);
    733 }
    734 
    735 int perf_evlist__create_maps(struct perf_evlist *evlist,
    736 			     struct perf_target *target)
    737 {
    738 	evlist->threads = thread_map__new_str(target->pid, target->tid,
    739 					      target->uid);
    740 
    741 	if (evlist->threads == NULL)
    742 		return -1;
    743 
    744 	if (perf_target__has_task(target))
    745 		evlist->cpus = cpu_map__dummy_new();
    746 	else if (!perf_target__has_cpu(target) && !target->uses_mmap)
    747 		evlist->cpus = cpu_map__dummy_new();
    748 	else
    749 		evlist->cpus = cpu_map__new(target->cpu_list);
    750 
    751 	if (evlist->cpus == NULL)
    752 		goto out_delete_threads;
    753 
    754 	return 0;
    755 
    756 out_delete_threads:
    757 	thread_map__delete(evlist->threads);
    758 	return -1;
    759 }
    760 
    761 void perf_evlist__delete_maps(struct perf_evlist *evlist)
    762 {
    763 	cpu_map__delete(evlist->cpus);
    764 	thread_map__delete(evlist->threads);
    765 	evlist->cpus	= NULL;
    766 	evlist->threads = NULL;
    767 }
    768 
    769 int perf_evlist__apply_filters(struct perf_evlist *evlist)
    770 {
    771 	struct perf_evsel *evsel;
    772 	int err = 0;
    773 	const int ncpus = cpu_map__nr(evlist->cpus),
    774 		  nthreads = thread_map__nr(evlist->threads);
    775 
    776 	list_for_each_entry(evsel, &evlist->entries, node) {
    777 		if (evsel->filter == NULL)
    778 			continue;
    779 
    780 		err = perf_evsel__set_filter(evsel, ncpus, nthreads, evsel->filter);
    781 		if (err)
    782 			break;
    783 	}
    784 
    785 	return err;
    786 }
    787 
    788 int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
    789 {
    790 	struct perf_evsel *evsel;
    791 	int err = 0;
    792 	const int ncpus = cpu_map__nr(evlist->cpus),
    793 		  nthreads = thread_map__nr(evlist->threads);
    794 
    795 	list_for_each_entry(evsel, &evlist->entries, node) {
    796 		err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter);
    797 		if (err)
    798 			break;
    799 	}
    800 
    801 	return err;
    802 }
    803 
    804 bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
    805 {
    806 	struct perf_evsel *pos;
    807 
    808 	if (evlist->nr_entries == 1)
    809 		return true;
    810 
    811 	if (evlist->id_pos < 0 || evlist->is_pos < 0)
    812 		return false;
    813 
    814 	list_for_each_entry(pos, &evlist->entries, node) {
    815 		if (pos->id_pos != evlist->id_pos ||
    816 		    pos->is_pos != evlist->is_pos)
    817 			return false;
    818 	}
    819 
    820 	return true;
    821 }
    822 
    823 u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
    824 {
    825 	struct perf_evsel *evsel;
    826 
    827 	if (evlist->combined_sample_type)
    828 		return evlist->combined_sample_type;
    829 
    830 	list_for_each_entry(evsel, &evlist->entries, node)
    831 		evlist->combined_sample_type |= evsel->attr.sample_type;
    832 
    833 	return evlist->combined_sample_type;
    834 }
    835 
    836 u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist)
    837 {
    838 	evlist->combined_sample_type = 0;
    839 	return __perf_evlist__combined_sample_type(evlist);
    840 }
    841 
    842 bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
    843 {
    844 	struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
    845 	u64 read_format = first->attr.read_format;
    846 	u64 sample_type = first->attr.sample_type;
    847 
    848 	list_for_each_entry_continue(pos, &evlist->entries, node) {
    849 		if (read_format != pos->attr.read_format)
    850 			return false;
    851 	}
    852 
    853 	/* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */
    854 	if ((sample_type & PERF_SAMPLE_READ) &&
    855 	    !(read_format & PERF_FORMAT_ID)) {
    856 		return false;
    857 	}
    858 
    859 	return true;
    860 }
    861 
    862 u64 perf_evlist__read_format(struct perf_evlist *evlist)
    863 {
    864 	struct perf_evsel *first = perf_evlist__first(evlist);
    865 	return first->attr.read_format;
    866 }
    867 
    868 u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist)
    869 {
    870 	struct perf_evsel *first = perf_evlist__first(evlist);
    871 	struct perf_sample *data;
    872 	u64 sample_type;
    873 	u16 size = 0;
    874 
    875 	if (!first->attr.sample_id_all)
    876 		goto out;
    877 
    878 	sample_type = first->attr.sample_type;
    879 
    880 	if (sample_type & PERF_SAMPLE_TID)
    881 		size += sizeof(data->tid) * 2;
    882 
    883        if (sample_type & PERF_SAMPLE_TIME)
    884 		size += sizeof(data->time);
    885 
    886 	if (sample_type & PERF_SAMPLE_ID)
    887 		size += sizeof(data->id);
    888 
    889 	if (sample_type & PERF_SAMPLE_STREAM_ID)
    890 		size += sizeof(data->stream_id);
    891 
    892 	if (sample_type & PERF_SAMPLE_CPU)
    893 		size += sizeof(data->cpu) * 2;
    894 
    895 	if (sample_type & PERF_SAMPLE_IDENTIFIER)
    896 		size += sizeof(data->id);
    897 out:
    898 	return size;
    899 }
    900 
    901 bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
    902 {
    903 	struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
    904 
    905 	list_for_each_entry_continue(pos, &evlist->entries, node) {
    906 		if (first->attr.sample_id_all != pos->attr.sample_id_all)
    907 			return false;
    908 	}
    909 
    910 	return true;
    911 }
    912 
    913 bool perf_evlist__sample_id_all(struct perf_evlist *evlist)
    914 {
    915 	struct perf_evsel *first = perf_evlist__first(evlist);
    916 	return first->attr.sample_id_all;
    917 }
    918 
    919 void perf_evlist__set_selected(struct perf_evlist *evlist,
    920 			       struct perf_evsel *evsel)
    921 {
    922 	evlist->selected = evsel;
    923 }
    924 
    925 void perf_evlist__close(struct perf_evlist *evlist)
    926 {
    927 	struct perf_evsel *evsel;
    928 	int ncpus = cpu_map__nr(evlist->cpus);
    929 	int nthreads = thread_map__nr(evlist->threads);
    930 
    931 	list_for_each_entry_reverse(evsel, &evlist->entries, node)
    932 		perf_evsel__close(evsel, ncpus, nthreads);
    933 }
    934 
    935 int perf_evlist__open(struct perf_evlist *evlist)
    936 {
    937 	struct perf_evsel *evsel;
    938 	int err;
    939 
    940 	perf_evlist__update_id_pos(evlist);
    941 
    942 	list_for_each_entry(evsel, &evlist->entries, node) {
    943 		err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
    944 		if (err < 0)
    945 			goto out_err;
    946 	}
    947 
    948 	return 0;
    949 out_err:
    950 	perf_evlist__close(evlist);
    951 	errno = -err;
    952 	return err;
    953 }
    954 
    955 int perf_evlist__prepare_workload(struct perf_evlist *evlist,
    956 				  struct perf_target *target,
    957 				  const char *argv[], bool pipe_output,
    958 				  bool want_signal)
    959 {
    960 	int child_ready_pipe[2], go_pipe[2];
    961 	char bf;
    962 
    963 	if (pipe(child_ready_pipe) < 0) {
    964 		perror("failed to create 'ready' pipe");
    965 		return -1;
    966 	}
    967 
    968 	if (pipe(go_pipe) < 0) {
    969 		perror("failed to create 'go' pipe");
    970 		goto out_close_ready_pipe;
    971 	}
    972 
    973 	evlist->workload.pid = fork();
    974 	if (evlist->workload.pid < 0) {
    975 		perror("failed to fork");
    976 		goto out_close_pipes;
    977 	}
    978 
    979 	if (!evlist->workload.pid) {
    980 		if (pipe_output)
    981 			dup2(2, 1);
    982 
    983 		signal(SIGTERM, SIG_DFL);
    984 
    985 		close(child_ready_pipe[0]);
    986 		close(go_pipe[1]);
    987 		fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
    988 
    989 		/*
    990 		 * Tell the parent we're ready to go
    991 		 */
    992 		close(child_ready_pipe[1]);
    993 
    994 		/*
    995 		 * Wait until the parent tells us to go.
    996 		 */
    997 		if (read(go_pipe[0], &bf, 1) == -1)
    998 			perror("unable to read pipe");
    999 
   1000 		execvp(argv[0], (char **)argv);
   1001 
   1002 		perror(argv[0]);
   1003 		if (want_signal)
   1004 			kill(getppid(), SIGUSR1);
   1005 		exit(-1);
   1006 	}
   1007 
   1008 	if (perf_target__none(target))
   1009 		evlist->threads->map[0] = evlist->workload.pid;
   1010 
   1011 	close(child_ready_pipe[1]);
   1012 	close(go_pipe[0]);
   1013 	/*
   1014 	 * wait for child to settle
   1015 	 */
   1016 	if (read(child_ready_pipe[0], &bf, 1) == -1) {
   1017 		perror("unable to read pipe");
   1018 		goto out_close_pipes;
   1019 	}
   1020 
   1021 	fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
   1022 	evlist->workload.cork_fd = go_pipe[1];
   1023 	close(child_ready_pipe[0]);
   1024 	return 0;
   1025 
   1026 out_close_pipes:
   1027 	close(go_pipe[0]);
   1028 	close(go_pipe[1]);
   1029 out_close_ready_pipe:
   1030 	close(child_ready_pipe[0]);
   1031 	close(child_ready_pipe[1]);
   1032 	return -1;
   1033 }
   1034 
   1035 int perf_evlist__start_workload(struct perf_evlist *evlist)
   1036 {
   1037 	if (evlist->workload.cork_fd > 0) {
   1038 		char bf = 0;
   1039 		int ret;
   1040 		/*
   1041 		 * Remove the cork, let it rip!
   1042 		 */
   1043 		ret = write(evlist->workload.cork_fd, &bf, 1);
   1044 		if (ret < 0)
   1045 			perror("enable to write to pipe");
   1046 
   1047 		close(evlist->workload.cork_fd);
   1048 		return ret;
   1049 	}
   1050 
   1051 	return 0;
   1052 }
   1053 
   1054 int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
   1055 			      struct perf_sample *sample)
   1056 {
   1057 	struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event);
   1058 
   1059 	if (!evsel)
   1060 		return -EFAULT;
   1061 	return perf_evsel__parse_sample(evsel, event, sample);
   1062 }
   1063 
   1064 size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
   1065 {
   1066 	struct perf_evsel *evsel;
   1067 	size_t printed = 0;
   1068 
   1069 	list_for_each_entry(evsel, &evlist->entries, node) {
   1070 		printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
   1071 				   perf_evsel__name(evsel));
   1072 	}
   1073 
   1074 	return printed + fprintf(fp, "\n");;
   1075 }
   1076