xref: /openbmc/linux/tools/perf/util/evlist.c (revision 75562573)
1f8a95309SArnaldo Carvalho de Melo /*
2f8a95309SArnaldo Carvalho de Melo  * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3f8a95309SArnaldo Carvalho de Melo  *
4f8a95309SArnaldo Carvalho de Melo  * Parts came from builtin-{top,stat,record}.c, see those files for further
5f8a95309SArnaldo Carvalho de Melo  * copyright notes.
6f8a95309SArnaldo Carvalho de Melo  *
7f8a95309SArnaldo Carvalho de Melo  * Released under the GPL v2. (and only v2, not any later version)
8f8a95309SArnaldo Carvalho de Melo  */
9a8c9ae18SArnaldo Carvalho de Melo #include "util.h"
1085c66be1SBorislav Petkov #include <lk/debugfs.h>
115c581041SArnaldo Carvalho de Melo #include <poll.h>
12f8a95309SArnaldo Carvalho de Melo #include "cpumap.h"
13f8a95309SArnaldo Carvalho de Melo #include "thread_map.h"
1412864b31SNamhyung Kim #include "target.h"
15361c99a6SArnaldo Carvalho de Melo #include "evlist.h"
16361c99a6SArnaldo Carvalho de Melo #include "evsel.h"
17e3e1a54fSAdrian Hunter #include "debug.h"
1835b9d88eSArnaldo Carvalho de Melo #include <unistd.h>
19361c99a6SArnaldo Carvalho de Melo 
2050d08e47SArnaldo Carvalho de Melo #include "parse-events.h"
2150d08e47SArnaldo Carvalho de Melo 
22f8a95309SArnaldo Carvalho de Melo #include <sys/mman.h>
23f8a95309SArnaldo Carvalho de Melo 
2470db7533SArnaldo Carvalho de Melo #include <linux/bitops.h>
2570db7533SArnaldo Carvalho de Melo #include <linux/hash.h>
2670db7533SArnaldo Carvalho de Melo 
27f8a95309SArnaldo Carvalho de Melo #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
28a91e5431SArnaldo Carvalho de Melo #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
29f8a95309SArnaldo Carvalho de Melo 
307e2ed097SArnaldo Carvalho de Melo void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
317e2ed097SArnaldo Carvalho de Melo 		       struct thread_map *threads)
32361c99a6SArnaldo Carvalho de Melo {
3370db7533SArnaldo Carvalho de Melo 	int i;
3470db7533SArnaldo Carvalho de Melo 
3570db7533SArnaldo Carvalho de Melo 	for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
3670db7533SArnaldo Carvalho de Melo 		INIT_HLIST_HEAD(&evlist->heads[i]);
37361c99a6SArnaldo Carvalho de Melo 	INIT_LIST_HEAD(&evlist->entries);
387e2ed097SArnaldo Carvalho de Melo 	perf_evlist__set_maps(evlist, cpus, threads);
3935b9d88eSArnaldo Carvalho de Melo 	evlist->workload.pid = -1;
40361c99a6SArnaldo Carvalho de Melo }
41361c99a6SArnaldo Carvalho de Melo 
42334fe7a3SNamhyung Kim struct perf_evlist *perf_evlist__new(void)
43ef1d1af2SArnaldo Carvalho de Melo {
44ef1d1af2SArnaldo Carvalho de Melo 	struct perf_evlist *evlist = zalloc(sizeof(*evlist));
45ef1d1af2SArnaldo Carvalho de Melo 
46ef1d1af2SArnaldo Carvalho de Melo 	if (evlist != NULL)
47334fe7a3SNamhyung Kim 		perf_evlist__init(evlist, NULL, NULL);
48ef1d1af2SArnaldo Carvalho de Melo 
49361c99a6SArnaldo Carvalho de Melo 	return evlist;
50361c99a6SArnaldo Carvalho de Melo }
51361c99a6SArnaldo Carvalho de Melo 
5275562573SAdrian Hunter /**
5375562573SAdrian Hunter  * perf_evlist__set_id_pos - set the positions of event ids.
5475562573SAdrian Hunter  * @evlist: selected event list
5575562573SAdrian Hunter  *
5675562573SAdrian Hunter  * Events with compatible sample types all have the same id_pos
5775562573SAdrian Hunter  * and is_pos.  For convenience, put a copy on evlist.
5875562573SAdrian Hunter  */
5975562573SAdrian Hunter void perf_evlist__set_id_pos(struct perf_evlist *evlist)
6075562573SAdrian Hunter {
6175562573SAdrian Hunter 	struct perf_evsel *first = perf_evlist__first(evlist);
6275562573SAdrian Hunter 
6375562573SAdrian Hunter 	evlist->id_pos = first->id_pos;
6475562573SAdrian Hunter 	evlist->is_pos = first->is_pos;
6575562573SAdrian Hunter }
6675562573SAdrian Hunter 
67361c99a6SArnaldo Carvalho de Melo static void perf_evlist__purge(struct perf_evlist *evlist)
68361c99a6SArnaldo Carvalho de Melo {
69361c99a6SArnaldo Carvalho de Melo 	struct perf_evsel *pos, *n;
70361c99a6SArnaldo Carvalho de Melo 
71361c99a6SArnaldo Carvalho de Melo 	list_for_each_entry_safe(pos, n, &evlist->entries, node) {
72361c99a6SArnaldo Carvalho de Melo 		list_del_init(&pos->node);
73361c99a6SArnaldo Carvalho de Melo 		perf_evsel__delete(pos);
74361c99a6SArnaldo Carvalho de Melo 	}
75361c99a6SArnaldo Carvalho de Melo 
76361c99a6SArnaldo Carvalho de Melo 	evlist->nr_entries = 0;
77361c99a6SArnaldo Carvalho de Melo }
78361c99a6SArnaldo Carvalho de Melo 
79ef1d1af2SArnaldo Carvalho de Melo void perf_evlist__exit(struct perf_evlist *evlist)
80ef1d1af2SArnaldo Carvalho de Melo {
81ef1d1af2SArnaldo Carvalho de Melo 	free(evlist->mmap);
82ef1d1af2SArnaldo Carvalho de Melo 	free(evlist->pollfd);
83ef1d1af2SArnaldo Carvalho de Melo 	evlist->mmap = NULL;
84ef1d1af2SArnaldo Carvalho de Melo 	evlist->pollfd = NULL;
85ef1d1af2SArnaldo Carvalho de Melo }
86ef1d1af2SArnaldo Carvalho de Melo 
87361c99a6SArnaldo Carvalho de Melo void perf_evlist__delete(struct perf_evlist *evlist)
88361c99a6SArnaldo Carvalho de Melo {
89361c99a6SArnaldo Carvalho de Melo 	perf_evlist__purge(evlist);
90ef1d1af2SArnaldo Carvalho de Melo 	perf_evlist__exit(evlist);
91361c99a6SArnaldo Carvalho de Melo 	free(evlist);
92361c99a6SArnaldo Carvalho de Melo }
93361c99a6SArnaldo Carvalho de Melo 
94361c99a6SArnaldo Carvalho de Melo void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
95361c99a6SArnaldo Carvalho de Melo {
96361c99a6SArnaldo Carvalho de Melo 	list_add_tail(&entry->node, &evlist->entries);
9775562573SAdrian Hunter 	if (!evlist->nr_entries++)
9875562573SAdrian Hunter 		perf_evlist__set_id_pos(evlist);
99361c99a6SArnaldo Carvalho de Melo }
100361c99a6SArnaldo Carvalho de Melo 
1010529bc1fSJiri Olsa void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
10250d08e47SArnaldo Carvalho de Melo 				   struct list_head *list,
10350d08e47SArnaldo Carvalho de Melo 				   int nr_entries)
10450d08e47SArnaldo Carvalho de Melo {
10575562573SAdrian Hunter 	bool set_id_pos = !evlist->nr_entries;
10675562573SAdrian Hunter 
10750d08e47SArnaldo Carvalho de Melo 	list_splice_tail(list, &evlist->entries);
10850d08e47SArnaldo Carvalho de Melo 	evlist->nr_entries += nr_entries;
10975562573SAdrian Hunter 	if (set_id_pos)
11075562573SAdrian Hunter 		perf_evlist__set_id_pos(evlist);
11150d08e47SArnaldo Carvalho de Melo }
11250d08e47SArnaldo Carvalho de Melo 
11363dab225SArnaldo Carvalho de Melo void __perf_evlist__set_leader(struct list_head *list)
11463dab225SArnaldo Carvalho de Melo {
11563dab225SArnaldo Carvalho de Melo 	struct perf_evsel *evsel, *leader;
11663dab225SArnaldo Carvalho de Melo 
11763dab225SArnaldo Carvalho de Melo 	leader = list_entry(list->next, struct perf_evsel, node);
11897f63e4aSNamhyung Kim 	evsel = list_entry(list->prev, struct perf_evsel, node);
11997f63e4aSNamhyung Kim 
12097f63e4aSNamhyung Kim 	leader->nr_members = evsel->idx - leader->idx + 1;
12163dab225SArnaldo Carvalho de Melo 
12263dab225SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, list, node) {
12363dab225SArnaldo Carvalho de Melo 		evsel->leader = leader;
12463dab225SArnaldo Carvalho de Melo 	}
12563dab225SArnaldo Carvalho de Melo }
12663dab225SArnaldo Carvalho de Melo 
12763dab225SArnaldo Carvalho de Melo void perf_evlist__set_leader(struct perf_evlist *evlist)
1286a4bb04cSJiri Olsa {
12997f63e4aSNamhyung Kim 	if (evlist->nr_entries) {
13097f63e4aSNamhyung Kim 		evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0;
13163dab225SArnaldo Carvalho de Melo 		__perf_evlist__set_leader(&evlist->entries);
1326a4bb04cSJiri Olsa 	}
13397f63e4aSNamhyung Kim }
1346a4bb04cSJiri Olsa 
135361c99a6SArnaldo Carvalho de Melo int perf_evlist__add_default(struct perf_evlist *evlist)
136361c99a6SArnaldo Carvalho de Melo {
137361c99a6SArnaldo Carvalho de Melo 	struct perf_event_attr attr = {
138361c99a6SArnaldo Carvalho de Melo 		.type = PERF_TYPE_HARDWARE,
139361c99a6SArnaldo Carvalho de Melo 		.config = PERF_COUNT_HW_CPU_CYCLES,
140361c99a6SArnaldo Carvalho de Melo 	};
1411aed2671SJoerg Roedel 	struct perf_evsel *evsel;
142361c99a6SArnaldo Carvalho de Melo 
1431aed2671SJoerg Roedel 	event_attr_init(&attr);
1441aed2671SJoerg Roedel 
1451aed2671SJoerg Roedel 	evsel = perf_evsel__new(&attr, 0);
146361c99a6SArnaldo Carvalho de Melo 	if (evsel == NULL)
147cc2d86b0SStephane Eranian 		goto error;
148cc2d86b0SStephane Eranian 
149cc2d86b0SStephane Eranian 	/* use strdup() because free(evsel) assumes name is allocated */
150cc2d86b0SStephane Eranian 	evsel->name = strdup("cycles");
151cc2d86b0SStephane Eranian 	if (!evsel->name)
152cc2d86b0SStephane Eranian 		goto error_free;
153361c99a6SArnaldo Carvalho de Melo 
154361c99a6SArnaldo Carvalho de Melo 	perf_evlist__add(evlist, evsel);
155361c99a6SArnaldo Carvalho de Melo 	return 0;
156cc2d86b0SStephane Eranian error_free:
157cc2d86b0SStephane Eranian 	perf_evsel__delete(evsel);
158cc2d86b0SStephane Eranian error:
159cc2d86b0SStephane Eranian 	return -ENOMEM;
160361c99a6SArnaldo Carvalho de Melo }
1615c581041SArnaldo Carvalho de Melo 
162e60fc847SArnaldo Carvalho de Melo static int perf_evlist__add_attrs(struct perf_evlist *evlist,
16350d08e47SArnaldo Carvalho de Melo 				  struct perf_event_attr *attrs, size_t nr_attrs)
16450d08e47SArnaldo Carvalho de Melo {
16550d08e47SArnaldo Carvalho de Melo 	struct perf_evsel *evsel, *n;
16650d08e47SArnaldo Carvalho de Melo 	LIST_HEAD(head);
16750d08e47SArnaldo Carvalho de Melo 	size_t i;
16850d08e47SArnaldo Carvalho de Melo 
16950d08e47SArnaldo Carvalho de Melo 	for (i = 0; i < nr_attrs; i++) {
17050d08e47SArnaldo Carvalho de Melo 		evsel = perf_evsel__new(attrs + i, evlist->nr_entries + i);
17150d08e47SArnaldo Carvalho de Melo 		if (evsel == NULL)
17250d08e47SArnaldo Carvalho de Melo 			goto out_delete_partial_list;
17350d08e47SArnaldo Carvalho de Melo 		list_add_tail(&evsel->node, &head);
17450d08e47SArnaldo Carvalho de Melo 	}
17550d08e47SArnaldo Carvalho de Melo 
17650d08e47SArnaldo Carvalho de Melo 	perf_evlist__splice_list_tail(evlist, &head, nr_attrs);
17750d08e47SArnaldo Carvalho de Melo 
17850d08e47SArnaldo Carvalho de Melo 	return 0;
17950d08e47SArnaldo Carvalho de Melo 
18050d08e47SArnaldo Carvalho de Melo out_delete_partial_list:
18150d08e47SArnaldo Carvalho de Melo 	list_for_each_entry_safe(evsel, n, &head, node)
18250d08e47SArnaldo Carvalho de Melo 		perf_evsel__delete(evsel);
18350d08e47SArnaldo Carvalho de Melo 	return -1;
18450d08e47SArnaldo Carvalho de Melo }
18550d08e47SArnaldo Carvalho de Melo 
18679695e1bSArnaldo Carvalho de Melo int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
18779695e1bSArnaldo Carvalho de Melo 				     struct perf_event_attr *attrs, size_t nr_attrs)
18879695e1bSArnaldo Carvalho de Melo {
18979695e1bSArnaldo Carvalho de Melo 	size_t i;
19079695e1bSArnaldo Carvalho de Melo 
19179695e1bSArnaldo Carvalho de Melo 	for (i = 0; i < nr_attrs; i++)
19279695e1bSArnaldo Carvalho de Melo 		event_attr_init(attrs + i);
19379695e1bSArnaldo Carvalho de Melo 
19479695e1bSArnaldo Carvalho de Melo 	return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
19579695e1bSArnaldo Carvalho de Melo }
19679695e1bSArnaldo Carvalho de Melo 
197da378962SArnaldo Carvalho de Melo struct perf_evsel *
198ee29be62SArnaldo Carvalho de Melo perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
199ee29be62SArnaldo Carvalho de Melo {
200ee29be62SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
201ee29be62SArnaldo Carvalho de Melo 
202ee29be62SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
203ee29be62SArnaldo Carvalho de Melo 		if (evsel->attr.type   == PERF_TYPE_TRACEPOINT &&
204ee29be62SArnaldo Carvalho de Melo 		    (int)evsel->attr.config == id)
205ee29be62SArnaldo Carvalho de Melo 			return evsel;
206ee29be62SArnaldo Carvalho de Melo 	}
207ee29be62SArnaldo Carvalho de Melo 
208ee29be62SArnaldo Carvalho de Melo 	return NULL;
209ee29be62SArnaldo Carvalho de Melo }
210ee29be62SArnaldo Carvalho de Melo 
21139876e7dSArnaldo Carvalho de Melo int perf_evlist__add_newtp(struct perf_evlist *evlist,
21239876e7dSArnaldo Carvalho de Melo 			   const char *sys, const char *name, void *handler)
21339876e7dSArnaldo Carvalho de Melo {
21439876e7dSArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
21539876e7dSArnaldo Carvalho de Melo 
21639876e7dSArnaldo Carvalho de Melo 	evsel = perf_evsel__newtp(sys, name, evlist->nr_entries);
21739876e7dSArnaldo Carvalho de Melo 	if (evsel == NULL)
21839876e7dSArnaldo Carvalho de Melo 		return -1;
21939876e7dSArnaldo Carvalho de Melo 
22039876e7dSArnaldo Carvalho de Melo 	evsel->handler.func = handler;
22139876e7dSArnaldo Carvalho de Melo 	perf_evlist__add(evlist, evsel);
22239876e7dSArnaldo Carvalho de Melo 	return 0;
22339876e7dSArnaldo Carvalho de Melo }
22439876e7dSArnaldo Carvalho de Melo 
2254152ab37SArnaldo Carvalho de Melo void perf_evlist__disable(struct perf_evlist *evlist)
2264152ab37SArnaldo Carvalho de Melo {
2274152ab37SArnaldo Carvalho de Melo 	int cpu, thread;
2284152ab37SArnaldo Carvalho de Melo 	struct perf_evsel *pos;
229b3a319d5SNamhyung Kim 	int nr_cpus = cpu_map__nr(evlist->cpus);
230b3a319d5SNamhyung Kim 	int nr_threads = thread_map__nr(evlist->threads);
2314152ab37SArnaldo Carvalho de Melo 
232b3a319d5SNamhyung Kim 	for (cpu = 0; cpu < nr_cpus; cpu++) {
2334152ab37SArnaldo Carvalho de Melo 		list_for_each_entry(pos, &evlist->entries, node) {
234823254edSNamhyung Kim 			if (!perf_evsel__is_group_leader(pos))
2353fe4430dSJiri Olsa 				continue;
236b3a319d5SNamhyung Kim 			for (thread = 0; thread < nr_threads; thread++)
23755da8005SNamhyung Kim 				ioctl(FD(pos, cpu, thread),
23855da8005SNamhyung Kim 				      PERF_EVENT_IOC_DISABLE, 0);
2394152ab37SArnaldo Carvalho de Melo 		}
2404152ab37SArnaldo Carvalho de Melo 	}
2414152ab37SArnaldo Carvalho de Melo }
2424152ab37SArnaldo Carvalho de Melo 
243764e16a3SDavid Ahern void perf_evlist__enable(struct perf_evlist *evlist)
244764e16a3SDavid Ahern {
245764e16a3SDavid Ahern 	int cpu, thread;
246764e16a3SDavid Ahern 	struct perf_evsel *pos;
247b3a319d5SNamhyung Kim 	int nr_cpus = cpu_map__nr(evlist->cpus);
248b3a319d5SNamhyung Kim 	int nr_threads = thread_map__nr(evlist->threads);
249764e16a3SDavid Ahern 
250b3a319d5SNamhyung Kim 	for (cpu = 0; cpu < nr_cpus; cpu++) {
251764e16a3SDavid Ahern 		list_for_each_entry(pos, &evlist->entries, node) {
252823254edSNamhyung Kim 			if (!perf_evsel__is_group_leader(pos))
2533fe4430dSJiri Olsa 				continue;
254b3a319d5SNamhyung Kim 			for (thread = 0; thread < nr_threads; thread++)
25555da8005SNamhyung Kim 				ioctl(FD(pos, cpu, thread),
25655da8005SNamhyung Kim 				      PERF_EVENT_IOC_ENABLE, 0);
257764e16a3SDavid Ahern 		}
258764e16a3SDavid Ahern 	}
259764e16a3SDavid Ahern }
260764e16a3SDavid Ahern 
261806fb630SArnaldo Carvalho de Melo static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
2625c581041SArnaldo Carvalho de Melo {
263b3a319d5SNamhyung Kim 	int nr_cpus = cpu_map__nr(evlist->cpus);
264b3a319d5SNamhyung Kim 	int nr_threads = thread_map__nr(evlist->threads);
265b3a319d5SNamhyung Kim 	int nfds = nr_cpus * nr_threads * evlist->nr_entries;
2665c581041SArnaldo Carvalho de Melo 	evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
2675c581041SArnaldo Carvalho de Melo 	return evlist->pollfd != NULL ? 0 : -ENOMEM;
2685c581041SArnaldo Carvalho de Melo }
26970082dd9SArnaldo Carvalho de Melo 
27070082dd9SArnaldo Carvalho de Melo void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
27170082dd9SArnaldo Carvalho de Melo {
27270082dd9SArnaldo Carvalho de Melo 	fcntl(fd, F_SETFL, O_NONBLOCK);
27370082dd9SArnaldo Carvalho de Melo 	evlist->pollfd[evlist->nr_fds].fd = fd;
27470082dd9SArnaldo Carvalho de Melo 	evlist->pollfd[evlist->nr_fds].events = POLLIN;
27570082dd9SArnaldo Carvalho de Melo 	evlist->nr_fds++;
27670082dd9SArnaldo Carvalho de Melo }
27770db7533SArnaldo Carvalho de Melo 
278a91e5431SArnaldo Carvalho de Melo static void perf_evlist__id_hash(struct perf_evlist *evlist,
279a91e5431SArnaldo Carvalho de Melo 				 struct perf_evsel *evsel,
2803d3b5e95SArnaldo Carvalho de Melo 				 int cpu, int thread, u64 id)
2813d3b5e95SArnaldo Carvalho de Melo {
2823d3b5e95SArnaldo Carvalho de Melo 	int hash;
2833d3b5e95SArnaldo Carvalho de Melo 	struct perf_sample_id *sid = SID(evsel, cpu, thread);
2843d3b5e95SArnaldo Carvalho de Melo 
2853d3b5e95SArnaldo Carvalho de Melo 	sid->id = id;
2863d3b5e95SArnaldo Carvalho de Melo 	sid->evsel = evsel;
2873d3b5e95SArnaldo Carvalho de Melo 	hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
2883d3b5e95SArnaldo Carvalho de Melo 	hlist_add_head(&sid->node, &evlist->heads[hash]);
2893d3b5e95SArnaldo Carvalho de Melo }
2903d3b5e95SArnaldo Carvalho de Melo 
291a91e5431SArnaldo Carvalho de Melo void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
292a91e5431SArnaldo Carvalho de Melo 			 int cpu, int thread, u64 id)
293a91e5431SArnaldo Carvalho de Melo {
294a91e5431SArnaldo Carvalho de Melo 	perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
295a91e5431SArnaldo Carvalho de Melo 	evsel->id[evsel->ids++] = id;
296a91e5431SArnaldo Carvalho de Melo }
297a91e5431SArnaldo Carvalho de Melo 
298a91e5431SArnaldo Carvalho de Melo static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
2993d3b5e95SArnaldo Carvalho de Melo 				  struct perf_evsel *evsel,
300f8a95309SArnaldo Carvalho de Melo 				  int cpu, int thread, int fd)
301f8a95309SArnaldo Carvalho de Melo {
302f8a95309SArnaldo Carvalho de Melo 	u64 read_data[4] = { 0, };
3033d3b5e95SArnaldo Carvalho de Melo 	int id_idx = 1; /* The first entry is the counter value */
304e2b5abe0SJiri Olsa 	u64 id;
305e2b5abe0SJiri Olsa 	int ret;
306e2b5abe0SJiri Olsa 
307e2b5abe0SJiri Olsa 	ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
308e2b5abe0SJiri Olsa 	if (!ret)
309e2b5abe0SJiri Olsa 		goto add;
310e2b5abe0SJiri Olsa 
311e2b5abe0SJiri Olsa 	if (errno != ENOTTY)
312e2b5abe0SJiri Olsa 		return -1;
313e2b5abe0SJiri Olsa 
314e2b5abe0SJiri Olsa 	/* Legacy way to get event id.. All hail to old kernels! */
315f8a95309SArnaldo Carvalho de Melo 
316c4861afeSJiri Olsa 	/*
317c4861afeSJiri Olsa 	 * This way does not work with group format read, so bail
318c4861afeSJiri Olsa 	 * out in that case.
319c4861afeSJiri Olsa 	 */
320c4861afeSJiri Olsa 	if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
321c4861afeSJiri Olsa 		return -1;
322c4861afeSJiri Olsa 
323f8a95309SArnaldo Carvalho de Melo 	if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
324f8a95309SArnaldo Carvalho de Melo 	    read(fd, &read_data, sizeof(read_data)) == -1)
325f8a95309SArnaldo Carvalho de Melo 		return -1;
326f8a95309SArnaldo Carvalho de Melo 
327f8a95309SArnaldo Carvalho de Melo 	if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
328f8a95309SArnaldo Carvalho de Melo 		++id_idx;
329f8a95309SArnaldo Carvalho de Melo 	if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
330f8a95309SArnaldo Carvalho de Melo 		++id_idx;
331f8a95309SArnaldo Carvalho de Melo 
332e2b5abe0SJiri Olsa 	id = read_data[id_idx];
333e2b5abe0SJiri Olsa 
334e2b5abe0SJiri Olsa  add:
335e2b5abe0SJiri Olsa 	perf_evlist__id_add(evlist, evsel, cpu, thread, id);
336f8a95309SArnaldo Carvalho de Melo 	return 0;
337f8a95309SArnaldo Carvalho de Melo }
338f8a95309SArnaldo Carvalho de Melo 
339932a3594SJiri Olsa struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id)
34070db7533SArnaldo Carvalho de Melo {
34170db7533SArnaldo Carvalho de Melo 	struct hlist_head *head;
34270db7533SArnaldo Carvalho de Melo 	struct perf_sample_id *sid;
34370db7533SArnaldo Carvalho de Melo 	int hash;
34470db7533SArnaldo Carvalho de Melo 
34570db7533SArnaldo Carvalho de Melo 	hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
34670db7533SArnaldo Carvalho de Melo 	head = &evlist->heads[hash];
34770db7533SArnaldo Carvalho de Melo 
348b67bfe0dSSasha Levin 	hlist_for_each_entry(sid, head, node)
34970db7533SArnaldo Carvalho de Melo 		if (sid->id == id)
350932a3594SJiri Olsa 			return sid;
351932a3594SJiri Olsa 
352932a3594SJiri Olsa 	return NULL;
353932a3594SJiri Olsa }
354932a3594SJiri Olsa 
355932a3594SJiri Olsa struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
356932a3594SJiri Olsa {
357932a3594SJiri Olsa 	struct perf_sample_id *sid;
358932a3594SJiri Olsa 
359932a3594SJiri Olsa 	if (evlist->nr_entries == 1)
360932a3594SJiri Olsa 		return perf_evlist__first(evlist);
361932a3594SJiri Olsa 
362932a3594SJiri Olsa 	sid = perf_evlist__id2sid(evlist, id);
363932a3594SJiri Olsa 	if (sid)
36470db7533SArnaldo Carvalho de Melo 		return sid->evsel;
36530e68bccSNamhyung Kim 
36630e68bccSNamhyung Kim 	if (!perf_evlist__sample_id_all(evlist))
3670c21f736SArnaldo Carvalho de Melo 		return perf_evlist__first(evlist);
36830e68bccSNamhyung Kim 
36970db7533SArnaldo Carvalho de Melo 	return NULL;
37070db7533SArnaldo Carvalho de Melo }
37104391debSArnaldo Carvalho de Melo 
37275562573SAdrian Hunter static int perf_evlist__event2id(struct perf_evlist *evlist,
37375562573SAdrian Hunter 				 union perf_event *event, u64 *id)
37475562573SAdrian Hunter {
37575562573SAdrian Hunter 	const u64 *array = event->sample.array;
37675562573SAdrian Hunter 	ssize_t n;
37775562573SAdrian Hunter 
37875562573SAdrian Hunter 	n = (event->header.size - sizeof(event->header)) >> 3;
37975562573SAdrian Hunter 
38075562573SAdrian Hunter 	if (event->header.type == PERF_RECORD_SAMPLE) {
38175562573SAdrian Hunter 		if (evlist->id_pos >= n)
38275562573SAdrian Hunter 			return -1;
38375562573SAdrian Hunter 		*id = array[evlist->id_pos];
38475562573SAdrian Hunter 	} else {
38575562573SAdrian Hunter 		if (evlist->is_pos > n)
38675562573SAdrian Hunter 			return -1;
38775562573SAdrian Hunter 		n -= evlist->is_pos;
38875562573SAdrian Hunter 		*id = array[n];
38975562573SAdrian Hunter 	}
39075562573SAdrian Hunter 	return 0;
39175562573SAdrian Hunter }
39275562573SAdrian Hunter 
39375562573SAdrian Hunter static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
39475562573SAdrian Hunter 						   union perf_event *event)
39575562573SAdrian Hunter {
39675562573SAdrian Hunter 	struct hlist_head *head;
39775562573SAdrian Hunter 	struct perf_sample_id *sid;
39875562573SAdrian Hunter 	int hash;
39975562573SAdrian Hunter 	u64 id;
40075562573SAdrian Hunter 
40175562573SAdrian Hunter 	if (evlist->nr_entries == 1)
40275562573SAdrian Hunter 		return perf_evlist__first(evlist);
40375562573SAdrian Hunter 
40475562573SAdrian Hunter 	if (perf_evlist__event2id(evlist, event, &id))
40575562573SAdrian Hunter 		return NULL;
40675562573SAdrian Hunter 
40775562573SAdrian Hunter 	/* Synthesized events have an id of zero */
40875562573SAdrian Hunter 	if (!id)
40975562573SAdrian Hunter 		return perf_evlist__first(evlist);
41075562573SAdrian Hunter 
41175562573SAdrian Hunter 	hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
41275562573SAdrian Hunter 	head = &evlist->heads[hash];
41375562573SAdrian Hunter 
41475562573SAdrian Hunter 	hlist_for_each_entry(sid, head, node) {
41575562573SAdrian Hunter 		if (sid->id == id)
41675562573SAdrian Hunter 			return sid->evsel;
41775562573SAdrian Hunter 	}
41875562573SAdrian Hunter 	return NULL;
41975562573SAdrian Hunter }
42075562573SAdrian Hunter 
421aece948fSArnaldo Carvalho de Melo union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
42204391debSArnaldo Carvalho de Melo {
423aece948fSArnaldo Carvalho de Melo 	struct perf_mmap *md = &evlist->mmap[idx];
42404391debSArnaldo Carvalho de Melo 	unsigned int head = perf_mmap__read_head(md);
42504391debSArnaldo Carvalho de Melo 	unsigned int old = md->prev;
42604391debSArnaldo Carvalho de Melo 	unsigned char *data = md->base + page_size;
4278115d60cSArnaldo Carvalho de Melo 	union perf_event *event = NULL;
42804391debSArnaldo Carvalho de Melo 
4297bb41152SArnaldo Carvalho de Melo 	if (evlist->overwrite) {
43004391debSArnaldo Carvalho de Melo 		/*
43104391debSArnaldo Carvalho de Melo 		 * If we're further behind than half the buffer, there's a chance
43204391debSArnaldo Carvalho de Melo 		 * the writer will bite our tail and mess up the samples under us.
43304391debSArnaldo Carvalho de Melo 		 *
43404391debSArnaldo Carvalho de Melo 		 * If we somehow ended up ahead of the head, we got messed up.
43504391debSArnaldo Carvalho de Melo 		 *
43604391debSArnaldo Carvalho de Melo 		 * In either case, truncate and restart at head.
43704391debSArnaldo Carvalho de Melo 		 */
4387bb41152SArnaldo Carvalho de Melo 		int diff = head - old;
43904391debSArnaldo Carvalho de Melo 		if (diff > md->mask / 2 || diff < 0) {
44004391debSArnaldo Carvalho de Melo 			fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
44104391debSArnaldo Carvalho de Melo 
44204391debSArnaldo Carvalho de Melo 			/*
44304391debSArnaldo Carvalho de Melo 			 * head points to a known good entry, start there.
44404391debSArnaldo Carvalho de Melo 			 */
44504391debSArnaldo Carvalho de Melo 			old = head;
44604391debSArnaldo Carvalho de Melo 		}
4477bb41152SArnaldo Carvalho de Melo 	}
44804391debSArnaldo Carvalho de Melo 
44904391debSArnaldo Carvalho de Melo 	if (old != head) {
45004391debSArnaldo Carvalho de Melo 		size_t size;
45104391debSArnaldo Carvalho de Melo 
4528115d60cSArnaldo Carvalho de Melo 		event = (union perf_event *)&data[old & md->mask];
45304391debSArnaldo Carvalho de Melo 		size = event->header.size;
45404391debSArnaldo Carvalho de Melo 
45504391debSArnaldo Carvalho de Melo 		/*
45604391debSArnaldo Carvalho de Melo 		 * Event straddles the mmap boundary -- header should always
45704391debSArnaldo Carvalho de Melo 		 * be inside due to u64 alignment of output.
45804391debSArnaldo Carvalho de Melo 		 */
45904391debSArnaldo Carvalho de Melo 		if ((old & md->mask) + size != ((old + size) & md->mask)) {
46004391debSArnaldo Carvalho de Melo 			unsigned int offset = old;
46104391debSArnaldo Carvalho de Melo 			unsigned int len = min(sizeof(*event), size), cpy;
4620479b8b9SDavid Ahern 			void *dst = &md->event_copy;
46304391debSArnaldo Carvalho de Melo 
46404391debSArnaldo Carvalho de Melo 			do {
46504391debSArnaldo Carvalho de Melo 				cpy = min(md->mask + 1 - (offset & md->mask), len);
46604391debSArnaldo Carvalho de Melo 				memcpy(dst, &data[offset & md->mask], cpy);
46704391debSArnaldo Carvalho de Melo 				offset += cpy;
46804391debSArnaldo Carvalho de Melo 				dst += cpy;
46904391debSArnaldo Carvalho de Melo 				len -= cpy;
47004391debSArnaldo Carvalho de Melo 			} while (len);
47104391debSArnaldo Carvalho de Melo 
4720479b8b9SDavid Ahern 			event = &md->event_copy;
47304391debSArnaldo Carvalho de Melo 		}
47404391debSArnaldo Carvalho de Melo 
47504391debSArnaldo Carvalho de Melo 		old += size;
47604391debSArnaldo Carvalho de Melo 	}
47704391debSArnaldo Carvalho de Melo 
47804391debSArnaldo Carvalho de Melo 	md->prev = old;
4797bb41152SArnaldo Carvalho de Melo 
4807bb41152SArnaldo Carvalho de Melo 	if (!evlist->overwrite)
4817bb41152SArnaldo Carvalho de Melo 		perf_mmap__write_tail(md, old);
4827bb41152SArnaldo Carvalho de Melo 
48304391debSArnaldo Carvalho de Melo 	return event;
48404391debSArnaldo Carvalho de Melo }
485f8a95309SArnaldo Carvalho de Melo 
48693edcbd9SAdrian Hunter static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
48793edcbd9SAdrian Hunter {
48893edcbd9SAdrian Hunter 	if (evlist->mmap[idx].base != NULL) {
48993edcbd9SAdrian Hunter 		munmap(evlist->mmap[idx].base, evlist->mmap_len);
49093edcbd9SAdrian Hunter 		evlist->mmap[idx].base = NULL;
49193edcbd9SAdrian Hunter 	}
49293edcbd9SAdrian Hunter }
49393edcbd9SAdrian Hunter 
4947e2ed097SArnaldo Carvalho de Melo void perf_evlist__munmap(struct perf_evlist *evlist)
495f8a95309SArnaldo Carvalho de Melo {
496aece948fSArnaldo Carvalho de Melo 	int i;
497f8a95309SArnaldo Carvalho de Melo 
49893edcbd9SAdrian Hunter 	for (i = 0; i < evlist->nr_mmaps; i++)
49993edcbd9SAdrian Hunter 		__perf_evlist__munmap(evlist, i);
500aece948fSArnaldo Carvalho de Melo 
501aece948fSArnaldo Carvalho de Melo 	free(evlist->mmap);
502aece948fSArnaldo Carvalho de Melo 	evlist->mmap = NULL;
503f8a95309SArnaldo Carvalho de Melo }
504f8a95309SArnaldo Carvalho de Melo 
505806fb630SArnaldo Carvalho de Melo static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
506f8a95309SArnaldo Carvalho de Melo {
507a14bb7a6SArnaldo Carvalho de Melo 	evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
508ec1e7e43SSukadev Bhattiprolu 	if (cpu_map__empty(evlist->cpus))
509b3a319d5SNamhyung Kim 		evlist->nr_mmaps = thread_map__nr(evlist->threads);
510aece948fSArnaldo Carvalho de Melo 	evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
511f8a95309SArnaldo Carvalho de Melo 	return evlist->mmap != NULL ? 0 : -ENOMEM;
512f8a95309SArnaldo Carvalho de Melo }
513f8a95309SArnaldo Carvalho de Melo 
514bccdaba0SArnaldo Carvalho de Melo static int __perf_evlist__mmap(struct perf_evlist *evlist,
515aece948fSArnaldo Carvalho de Melo 			       int idx, int prot, int mask, int fd)
516f8a95309SArnaldo Carvalho de Melo {
517aece948fSArnaldo Carvalho de Melo 	evlist->mmap[idx].prev = 0;
518aece948fSArnaldo Carvalho de Melo 	evlist->mmap[idx].mask = mask;
519aece948fSArnaldo Carvalho de Melo 	evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
520f8a95309SArnaldo Carvalho de Melo 				      MAP_SHARED, fd, 0);
521301b195dSNelson Elhage 	if (evlist->mmap[idx].base == MAP_FAILED) {
522301b195dSNelson Elhage 		evlist->mmap[idx].base = NULL;
523f8a95309SArnaldo Carvalho de Melo 		return -1;
524301b195dSNelson Elhage 	}
525f8a95309SArnaldo Carvalho de Melo 
526f8a95309SArnaldo Carvalho de Melo 	perf_evlist__add_pollfd(evlist, fd);
527f8a95309SArnaldo Carvalho de Melo 	return 0;
528f8a95309SArnaldo Carvalho de Melo }
529f8a95309SArnaldo Carvalho de Melo 
530aece948fSArnaldo Carvalho de Melo static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
531aece948fSArnaldo Carvalho de Melo {
532aece948fSArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
533aece948fSArnaldo Carvalho de Melo 	int cpu, thread;
534b3a319d5SNamhyung Kim 	int nr_cpus = cpu_map__nr(evlist->cpus);
535b3a319d5SNamhyung Kim 	int nr_threads = thread_map__nr(evlist->threads);
536aece948fSArnaldo Carvalho de Melo 
537e3e1a54fSAdrian Hunter 	pr_debug2("perf event ring buffer mmapped per cpu\n");
538b3a319d5SNamhyung Kim 	for (cpu = 0; cpu < nr_cpus; cpu++) {
539aece948fSArnaldo Carvalho de Melo 		int output = -1;
540aece948fSArnaldo Carvalho de Melo 
541b3a319d5SNamhyung Kim 		for (thread = 0; thread < nr_threads; thread++) {
542aece948fSArnaldo Carvalho de Melo 			list_for_each_entry(evsel, &evlist->entries, node) {
543aece948fSArnaldo Carvalho de Melo 				int fd = FD(evsel, cpu, thread);
544aece948fSArnaldo Carvalho de Melo 
545aece948fSArnaldo Carvalho de Melo 				if (output == -1) {
546aece948fSArnaldo Carvalho de Melo 					output = fd;
547bccdaba0SArnaldo Carvalho de Melo 					if (__perf_evlist__mmap(evlist, cpu,
548aece948fSArnaldo Carvalho de Melo 								prot, mask, output) < 0)
549aece948fSArnaldo Carvalho de Melo 						goto out_unmap;
550aece948fSArnaldo Carvalho de Melo 				} else {
551aece948fSArnaldo Carvalho de Melo 					if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
552aece948fSArnaldo Carvalho de Melo 						goto out_unmap;
553aece948fSArnaldo Carvalho de Melo 				}
554aece948fSArnaldo Carvalho de Melo 
555aece948fSArnaldo Carvalho de Melo 				if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
556aece948fSArnaldo Carvalho de Melo 				    perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
557aece948fSArnaldo Carvalho de Melo 					goto out_unmap;
558aece948fSArnaldo Carvalho de Melo 			}
559aece948fSArnaldo Carvalho de Melo 		}
560aece948fSArnaldo Carvalho de Melo 	}
561aece948fSArnaldo Carvalho de Melo 
562aece948fSArnaldo Carvalho de Melo 	return 0;
563aece948fSArnaldo Carvalho de Melo 
564aece948fSArnaldo Carvalho de Melo out_unmap:
56593edcbd9SAdrian Hunter 	for (cpu = 0; cpu < nr_cpus; cpu++)
56693edcbd9SAdrian Hunter 		__perf_evlist__munmap(evlist, cpu);
567aece948fSArnaldo Carvalho de Melo 	return -1;
568aece948fSArnaldo Carvalho de Melo }
569aece948fSArnaldo Carvalho de Melo 
570aece948fSArnaldo Carvalho de Melo static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
571aece948fSArnaldo Carvalho de Melo {
572aece948fSArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
573aece948fSArnaldo Carvalho de Melo 	int thread;
574b3a319d5SNamhyung Kim 	int nr_threads = thread_map__nr(evlist->threads);
575aece948fSArnaldo Carvalho de Melo 
576e3e1a54fSAdrian Hunter 	pr_debug2("perf event ring buffer mmapped per thread\n");
577b3a319d5SNamhyung Kim 	for (thread = 0; thread < nr_threads; thread++) {
578aece948fSArnaldo Carvalho de Melo 		int output = -1;
579aece948fSArnaldo Carvalho de Melo 
580aece948fSArnaldo Carvalho de Melo 		list_for_each_entry(evsel, &evlist->entries, node) {
581aece948fSArnaldo Carvalho de Melo 			int fd = FD(evsel, 0, thread);
582aece948fSArnaldo Carvalho de Melo 
583aece948fSArnaldo Carvalho de Melo 			if (output == -1) {
584aece948fSArnaldo Carvalho de Melo 				output = fd;
585bccdaba0SArnaldo Carvalho de Melo 				if (__perf_evlist__mmap(evlist, thread,
586aece948fSArnaldo Carvalho de Melo 							prot, mask, output) < 0)
587aece948fSArnaldo Carvalho de Melo 					goto out_unmap;
588aece948fSArnaldo Carvalho de Melo 			} else {
589aece948fSArnaldo Carvalho de Melo 				if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
590aece948fSArnaldo Carvalho de Melo 					goto out_unmap;
591aece948fSArnaldo Carvalho de Melo 			}
592aece948fSArnaldo Carvalho de Melo 
593aece948fSArnaldo Carvalho de Melo 			if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
594aece948fSArnaldo Carvalho de Melo 			    perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
595aece948fSArnaldo Carvalho de Melo 				goto out_unmap;
596aece948fSArnaldo Carvalho de Melo 		}
597aece948fSArnaldo Carvalho de Melo 	}
598aece948fSArnaldo Carvalho de Melo 
599aece948fSArnaldo Carvalho de Melo 	return 0;
600aece948fSArnaldo Carvalho de Melo 
601aece948fSArnaldo Carvalho de Melo out_unmap:
60293edcbd9SAdrian Hunter 	for (thread = 0; thread < nr_threads; thread++)
60393edcbd9SAdrian Hunter 		__perf_evlist__munmap(evlist, thread);
604aece948fSArnaldo Carvalho de Melo 	return -1;
605aece948fSArnaldo Carvalho de Melo }
606aece948fSArnaldo Carvalho de Melo 
607f8a95309SArnaldo Carvalho de Melo /** perf_evlist__mmap - Create per cpu maps to receive events
608f8a95309SArnaldo Carvalho de Melo  *
609f8a95309SArnaldo Carvalho de Melo  * @evlist - list of events
610f8a95309SArnaldo Carvalho de Melo  * @pages - map length in pages
611f8a95309SArnaldo Carvalho de Melo  * @overwrite - overwrite older events?
612f8a95309SArnaldo Carvalho de Melo  *
613f8a95309SArnaldo Carvalho de Melo  * If overwrite is false the user needs to signal event consuption using:
614f8a95309SArnaldo Carvalho de Melo  *
615f8a95309SArnaldo Carvalho de Melo  *	struct perf_mmap *m = &evlist->mmap[cpu];
616f8a95309SArnaldo Carvalho de Melo  *	unsigned int head = perf_mmap__read_head(m);
617f8a95309SArnaldo Carvalho de Melo  *
618f8a95309SArnaldo Carvalho de Melo  *	perf_mmap__write_tail(m, head)
6197e2ed097SArnaldo Carvalho de Melo  *
6207e2ed097SArnaldo Carvalho de Melo  * Using perf_evlist__read_on_cpu does this automatically.
621f8a95309SArnaldo Carvalho de Melo  */
62250a682ceSArnaldo Carvalho de Melo int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
62350a682ceSArnaldo Carvalho de Melo 		      bool overwrite)
624f8a95309SArnaldo Carvalho de Melo {
625aece948fSArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
6267e2ed097SArnaldo Carvalho de Melo 	const struct cpu_map *cpus = evlist->cpus;
6277e2ed097SArnaldo Carvalho de Melo 	const struct thread_map *threads = evlist->threads;
62850a682ceSArnaldo Carvalho de Melo 	int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), mask;
62950a682ceSArnaldo Carvalho de Melo 
63050a682ceSArnaldo Carvalho de Melo         /* 512 kiB: default amount of unprivileged mlocked memory */
63150a682ceSArnaldo Carvalho de Melo         if (pages == UINT_MAX)
63250a682ceSArnaldo Carvalho de Melo                 pages = (512 * 1024) / page_size;
63341d0d933SNelson Elhage 	else if (!is_power_of_2(pages))
63441d0d933SNelson Elhage 		return -EINVAL;
63550a682ceSArnaldo Carvalho de Melo 
63650a682ceSArnaldo Carvalho de Melo 	mask = pages * page_size - 1;
637f8a95309SArnaldo Carvalho de Melo 
6387e2ed097SArnaldo Carvalho de Melo 	if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
639f8a95309SArnaldo Carvalho de Melo 		return -ENOMEM;
640f8a95309SArnaldo Carvalho de Melo 
6417e2ed097SArnaldo Carvalho de Melo 	if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
642f8a95309SArnaldo Carvalho de Melo 		return -ENOMEM;
643f8a95309SArnaldo Carvalho de Melo 
644f8a95309SArnaldo Carvalho de Melo 	evlist->overwrite = overwrite;
645f8a95309SArnaldo Carvalho de Melo 	evlist->mmap_len = (pages + 1) * page_size;
646f8a95309SArnaldo Carvalho de Melo 
647f8a95309SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
648f8a95309SArnaldo Carvalho de Melo 		if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
649a91e5431SArnaldo Carvalho de Melo 		    evsel->sample_id == NULL &&
650a14bb7a6SArnaldo Carvalho de Melo 		    perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
651f8a95309SArnaldo Carvalho de Melo 			return -ENOMEM;
652f8a95309SArnaldo Carvalho de Melo 	}
653f8a95309SArnaldo Carvalho de Melo 
654ec1e7e43SSukadev Bhattiprolu 	if (cpu_map__empty(cpus))
655aece948fSArnaldo Carvalho de Melo 		return perf_evlist__mmap_per_thread(evlist, prot, mask);
656f8a95309SArnaldo Carvalho de Melo 
657aece948fSArnaldo Carvalho de Melo 	return perf_evlist__mmap_per_cpu(evlist, prot, mask);
658f8a95309SArnaldo Carvalho de Melo }
6597e2ed097SArnaldo Carvalho de Melo 
660b809ac10SNamhyung Kim int perf_evlist__create_maps(struct perf_evlist *evlist,
661b809ac10SNamhyung Kim 			     struct perf_target *target)
6627e2ed097SArnaldo Carvalho de Melo {
663b809ac10SNamhyung Kim 	evlist->threads = thread_map__new_str(target->pid, target->tid,
664b809ac10SNamhyung Kim 					      target->uid);
6657e2ed097SArnaldo Carvalho de Melo 
6667e2ed097SArnaldo Carvalho de Melo 	if (evlist->threads == NULL)
6677e2ed097SArnaldo Carvalho de Melo 		return -1;
6687e2ed097SArnaldo Carvalho de Melo 
669879d77d0SNamhyung Kim 	if (perf_target__has_task(target))
670d67356e7SNamhyung Kim 		evlist->cpus = cpu_map__dummy_new();
671d1cb9fceSNamhyung Kim 	else if (!perf_target__has_cpu(target) && !target->uses_mmap)
672d1cb9fceSNamhyung Kim 		evlist->cpus = cpu_map__dummy_new();
673879d77d0SNamhyung Kim 	else
674879d77d0SNamhyung Kim 		evlist->cpus = cpu_map__new(target->cpu_list);
6757e2ed097SArnaldo Carvalho de Melo 
6767e2ed097SArnaldo Carvalho de Melo 	if (evlist->cpus == NULL)
6777e2ed097SArnaldo Carvalho de Melo 		goto out_delete_threads;
6787e2ed097SArnaldo Carvalho de Melo 
6797e2ed097SArnaldo Carvalho de Melo 	return 0;
6807e2ed097SArnaldo Carvalho de Melo 
6817e2ed097SArnaldo Carvalho de Melo out_delete_threads:
6827e2ed097SArnaldo Carvalho de Melo 	thread_map__delete(evlist->threads);
6837e2ed097SArnaldo Carvalho de Melo 	return -1;
6847e2ed097SArnaldo Carvalho de Melo }
6857e2ed097SArnaldo Carvalho de Melo 
6867e2ed097SArnaldo Carvalho de Melo void perf_evlist__delete_maps(struct perf_evlist *evlist)
6877e2ed097SArnaldo Carvalho de Melo {
6887e2ed097SArnaldo Carvalho de Melo 	cpu_map__delete(evlist->cpus);
6897e2ed097SArnaldo Carvalho de Melo 	thread_map__delete(evlist->threads);
6907e2ed097SArnaldo Carvalho de Melo 	evlist->cpus	= NULL;
6917e2ed097SArnaldo Carvalho de Melo 	evlist->threads = NULL;
6927e2ed097SArnaldo Carvalho de Melo }
6930a102479SFrederic Weisbecker 
6941491a632SArnaldo Carvalho de Melo int perf_evlist__apply_filters(struct perf_evlist *evlist)
6950a102479SFrederic Weisbecker {
6960a102479SFrederic Weisbecker 	struct perf_evsel *evsel;
697745cefc5SArnaldo Carvalho de Melo 	int err = 0;
698745cefc5SArnaldo Carvalho de Melo 	const int ncpus = cpu_map__nr(evlist->cpus),
699b3a319d5SNamhyung Kim 		  nthreads = thread_map__nr(evlist->threads);
7000a102479SFrederic Weisbecker 
7010a102479SFrederic Weisbecker 	list_for_each_entry(evsel, &evlist->entries, node) {
702745cefc5SArnaldo Carvalho de Melo 		if (evsel->filter == NULL)
7030a102479SFrederic Weisbecker 			continue;
704745cefc5SArnaldo Carvalho de Melo 
705745cefc5SArnaldo Carvalho de Melo 		err = perf_evsel__set_filter(evsel, ncpus, nthreads, evsel->filter);
7060a102479SFrederic Weisbecker 		if (err)
707745cefc5SArnaldo Carvalho de Melo 			break;
7080a102479SFrederic Weisbecker 	}
7090a102479SFrederic Weisbecker 
710745cefc5SArnaldo Carvalho de Melo 	return err;
711745cefc5SArnaldo Carvalho de Melo }
712745cefc5SArnaldo Carvalho de Melo 
713745cefc5SArnaldo Carvalho de Melo int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
714745cefc5SArnaldo Carvalho de Melo {
715745cefc5SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
716745cefc5SArnaldo Carvalho de Melo 	int err = 0;
717745cefc5SArnaldo Carvalho de Melo 	const int ncpus = cpu_map__nr(evlist->cpus),
718b3a319d5SNamhyung Kim 		  nthreads = thread_map__nr(evlist->threads);
719745cefc5SArnaldo Carvalho de Melo 
720745cefc5SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
721745cefc5SArnaldo Carvalho de Melo 		err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter);
722745cefc5SArnaldo Carvalho de Melo 		if (err)
723745cefc5SArnaldo Carvalho de Melo 			break;
724745cefc5SArnaldo Carvalho de Melo 	}
725745cefc5SArnaldo Carvalho de Melo 
726745cefc5SArnaldo Carvalho de Melo 	return err;
7270a102479SFrederic Weisbecker }
72874429964SFrederic Weisbecker 
7290c21f736SArnaldo Carvalho de Melo bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
73074429964SFrederic Weisbecker {
73175562573SAdrian Hunter 	struct perf_evsel *pos;
732c2a70653SArnaldo Carvalho de Melo 
73375562573SAdrian Hunter 	if (evlist->nr_entries == 1)
73475562573SAdrian Hunter 		return true;
73575562573SAdrian Hunter 
73675562573SAdrian Hunter 	if (evlist->id_pos < 0 || evlist->is_pos < 0)
73775562573SAdrian Hunter 		return false;
73875562573SAdrian Hunter 
73975562573SAdrian Hunter 	list_for_each_entry(pos, &evlist->entries, node) {
74075562573SAdrian Hunter 		if (pos->id_pos != evlist->id_pos ||
74175562573SAdrian Hunter 		    pos->is_pos != evlist->is_pos)
742c2a70653SArnaldo Carvalho de Melo 			return false;
74374429964SFrederic Weisbecker 	}
74474429964SFrederic Weisbecker 
745c2a70653SArnaldo Carvalho de Melo 	return true;
746c2a70653SArnaldo Carvalho de Melo }
747c2a70653SArnaldo Carvalho de Melo 
74875562573SAdrian Hunter u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
749c2a70653SArnaldo Carvalho de Melo {
75075562573SAdrian Hunter 	struct perf_evsel *evsel;
75175562573SAdrian Hunter 
75275562573SAdrian Hunter 	if (evlist->combined_sample_type)
75375562573SAdrian Hunter 		return evlist->combined_sample_type;
75475562573SAdrian Hunter 
75575562573SAdrian Hunter 	list_for_each_entry(evsel, &evlist->entries, node)
75675562573SAdrian Hunter 		evlist->combined_sample_type |= evsel->attr.sample_type;
75775562573SAdrian Hunter 
75875562573SAdrian Hunter 	return evlist->combined_sample_type;
75975562573SAdrian Hunter }
76075562573SAdrian Hunter 
76175562573SAdrian Hunter u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist)
76275562573SAdrian Hunter {
76375562573SAdrian Hunter 	evlist->combined_sample_type = 0;
76475562573SAdrian Hunter 	return __perf_evlist__combined_sample_type(evlist);
765c2a70653SArnaldo Carvalho de Melo }
766c2a70653SArnaldo Carvalho de Melo 
7679ede473cSJiri Olsa bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
7689ede473cSJiri Olsa {
7699ede473cSJiri Olsa 	struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
7709ede473cSJiri Olsa 	u64 read_format = first->attr.read_format;
7719ede473cSJiri Olsa 	u64 sample_type = first->attr.sample_type;
7729ede473cSJiri Olsa 
7739ede473cSJiri Olsa 	list_for_each_entry_continue(pos, &evlist->entries, node) {
7749ede473cSJiri Olsa 		if (read_format != pos->attr.read_format)
7759ede473cSJiri Olsa 			return false;
7769ede473cSJiri Olsa 	}
7779ede473cSJiri Olsa 
7789ede473cSJiri Olsa 	/* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */
7799ede473cSJiri Olsa 	if ((sample_type & PERF_SAMPLE_READ) &&
7809ede473cSJiri Olsa 	    !(read_format & PERF_FORMAT_ID)) {
7819ede473cSJiri Olsa 		return false;
7829ede473cSJiri Olsa 	}
7839ede473cSJiri Olsa 
7849ede473cSJiri Olsa 	return true;
7859ede473cSJiri Olsa }
7869ede473cSJiri Olsa 
7879ede473cSJiri Olsa u64 perf_evlist__read_format(struct perf_evlist *evlist)
7889ede473cSJiri Olsa {
7899ede473cSJiri Olsa 	struct perf_evsel *first = perf_evlist__first(evlist);
7909ede473cSJiri Olsa 	return first->attr.read_format;
7919ede473cSJiri Olsa }
7929ede473cSJiri Olsa 
7930c21f736SArnaldo Carvalho de Melo u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist)
79481e36bffSArnaldo Carvalho de Melo {
7950c21f736SArnaldo Carvalho de Melo 	struct perf_evsel *first = perf_evlist__first(evlist);
79681e36bffSArnaldo Carvalho de Melo 	struct perf_sample *data;
79781e36bffSArnaldo Carvalho de Melo 	u64 sample_type;
79881e36bffSArnaldo Carvalho de Melo 	u16 size = 0;
79981e36bffSArnaldo Carvalho de Melo 
80081e36bffSArnaldo Carvalho de Melo 	if (!first->attr.sample_id_all)
80181e36bffSArnaldo Carvalho de Melo 		goto out;
80281e36bffSArnaldo Carvalho de Melo 
80381e36bffSArnaldo Carvalho de Melo 	sample_type = first->attr.sample_type;
80481e36bffSArnaldo Carvalho de Melo 
80581e36bffSArnaldo Carvalho de Melo 	if (sample_type & PERF_SAMPLE_TID)
80681e36bffSArnaldo Carvalho de Melo 		size += sizeof(data->tid) * 2;
80781e36bffSArnaldo Carvalho de Melo 
80881e36bffSArnaldo Carvalho de Melo        if (sample_type & PERF_SAMPLE_TIME)
80981e36bffSArnaldo Carvalho de Melo 		size += sizeof(data->time);
81081e36bffSArnaldo Carvalho de Melo 
81181e36bffSArnaldo Carvalho de Melo 	if (sample_type & PERF_SAMPLE_ID)
81281e36bffSArnaldo Carvalho de Melo 		size += sizeof(data->id);
81381e36bffSArnaldo Carvalho de Melo 
81481e36bffSArnaldo Carvalho de Melo 	if (sample_type & PERF_SAMPLE_STREAM_ID)
81581e36bffSArnaldo Carvalho de Melo 		size += sizeof(data->stream_id);
81681e36bffSArnaldo Carvalho de Melo 
81781e36bffSArnaldo Carvalho de Melo 	if (sample_type & PERF_SAMPLE_CPU)
81881e36bffSArnaldo Carvalho de Melo 		size += sizeof(data->cpu) * 2;
81975562573SAdrian Hunter 
82075562573SAdrian Hunter 	if (sample_type & PERF_SAMPLE_IDENTIFIER)
82175562573SAdrian Hunter 		size += sizeof(data->id);
82281e36bffSArnaldo Carvalho de Melo out:
82381e36bffSArnaldo Carvalho de Melo 	return size;
82481e36bffSArnaldo Carvalho de Melo }
82581e36bffSArnaldo Carvalho de Melo 
8260c21f736SArnaldo Carvalho de Melo bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
827c2a70653SArnaldo Carvalho de Melo {
8280c21f736SArnaldo Carvalho de Melo 	struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
829c2a70653SArnaldo Carvalho de Melo 
830c2a70653SArnaldo Carvalho de Melo 	list_for_each_entry_continue(pos, &evlist->entries, node) {
831c2a70653SArnaldo Carvalho de Melo 		if (first->attr.sample_id_all != pos->attr.sample_id_all)
832c2a70653SArnaldo Carvalho de Melo 			return false;
833c2a70653SArnaldo Carvalho de Melo 	}
834c2a70653SArnaldo Carvalho de Melo 
835c2a70653SArnaldo Carvalho de Melo 	return true;
83674429964SFrederic Weisbecker }
83774429964SFrederic Weisbecker 
8380c21f736SArnaldo Carvalho de Melo bool perf_evlist__sample_id_all(struct perf_evlist *evlist)
83974429964SFrederic Weisbecker {
8400c21f736SArnaldo Carvalho de Melo 	struct perf_evsel *first = perf_evlist__first(evlist);
841c2a70653SArnaldo Carvalho de Melo 	return first->attr.sample_id_all;
84274429964SFrederic Weisbecker }
84381cce8deSArnaldo Carvalho de Melo 
84481cce8deSArnaldo Carvalho de Melo void perf_evlist__set_selected(struct perf_evlist *evlist,
84581cce8deSArnaldo Carvalho de Melo 			       struct perf_evsel *evsel)
84681cce8deSArnaldo Carvalho de Melo {
84781cce8deSArnaldo Carvalho de Melo 	evlist->selected = evsel;
84881cce8deSArnaldo Carvalho de Melo }
849727ab04eSArnaldo Carvalho de Melo 
850a74b4b66SNamhyung Kim void perf_evlist__close(struct perf_evlist *evlist)
851a74b4b66SNamhyung Kim {
852a74b4b66SNamhyung Kim 	struct perf_evsel *evsel;
853a74b4b66SNamhyung Kim 	int ncpus = cpu_map__nr(evlist->cpus);
854a74b4b66SNamhyung Kim 	int nthreads = thread_map__nr(evlist->threads);
855a74b4b66SNamhyung Kim 
856a74b4b66SNamhyung Kim 	list_for_each_entry_reverse(evsel, &evlist->entries, node)
857a74b4b66SNamhyung Kim 		perf_evsel__close(evsel, ncpus, nthreads);
858a74b4b66SNamhyung Kim }
859a74b4b66SNamhyung Kim 
8606a4bb04cSJiri Olsa int perf_evlist__open(struct perf_evlist *evlist)
861727ab04eSArnaldo Carvalho de Melo {
8626a4bb04cSJiri Olsa 	struct perf_evsel *evsel;
863a74b4b66SNamhyung Kim 	int err;
864727ab04eSArnaldo Carvalho de Melo 
865727ab04eSArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
8666a4bb04cSJiri Olsa 		err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
867727ab04eSArnaldo Carvalho de Melo 		if (err < 0)
868727ab04eSArnaldo Carvalho de Melo 			goto out_err;
869727ab04eSArnaldo Carvalho de Melo 	}
870727ab04eSArnaldo Carvalho de Melo 
871727ab04eSArnaldo Carvalho de Melo 	return 0;
872727ab04eSArnaldo Carvalho de Melo out_err:
873a74b4b66SNamhyung Kim 	perf_evlist__close(evlist);
87441c21a68SNamhyung Kim 	errno = -err;
875727ab04eSArnaldo Carvalho de Melo 	return err;
876727ab04eSArnaldo Carvalho de Melo }
87735b9d88eSArnaldo Carvalho de Melo 
87835b9d88eSArnaldo Carvalho de Melo int perf_evlist__prepare_workload(struct perf_evlist *evlist,
8796ef73ec4SNamhyung Kim 				  struct perf_target *target,
88055e162eaSNamhyung Kim 				  const char *argv[], bool pipe_output,
88155e162eaSNamhyung Kim 				  bool want_signal)
88235b9d88eSArnaldo Carvalho de Melo {
88335b9d88eSArnaldo Carvalho de Melo 	int child_ready_pipe[2], go_pipe[2];
88435b9d88eSArnaldo Carvalho de Melo 	char bf;
88535b9d88eSArnaldo Carvalho de Melo 
88635b9d88eSArnaldo Carvalho de Melo 	if (pipe(child_ready_pipe) < 0) {
88735b9d88eSArnaldo Carvalho de Melo 		perror("failed to create 'ready' pipe");
88835b9d88eSArnaldo Carvalho de Melo 		return -1;
88935b9d88eSArnaldo Carvalho de Melo 	}
89035b9d88eSArnaldo Carvalho de Melo 
89135b9d88eSArnaldo Carvalho de Melo 	if (pipe(go_pipe) < 0) {
89235b9d88eSArnaldo Carvalho de Melo 		perror("failed to create 'go' pipe");
89335b9d88eSArnaldo Carvalho de Melo 		goto out_close_ready_pipe;
89435b9d88eSArnaldo Carvalho de Melo 	}
89535b9d88eSArnaldo Carvalho de Melo 
89635b9d88eSArnaldo Carvalho de Melo 	evlist->workload.pid = fork();
89735b9d88eSArnaldo Carvalho de Melo 	if (evlist->workload.pid < 0) {
89835b9d88eSArnaldo Carvalho de Melo 		perror("failed to fork");
89935b9d88eSArnaldo Carvalho de Melo 		goto out_close_pipes;
90035b9d88eSArnaldo Carvalho de Melo 	}
90135b9d88eSArnaldo Carvalho de Melo 
90235b9d88eSArnaldo Carvalho de Melo 	if (!evlist->workload.pid) {
903119fa3c9SNamhyung Kim 		if (pipe_output)
90435b9d88eSArnaldo Carvalho de Melo 			dup2(2, 1);
90535b9d88eSArnaldo Carvalho de Melo 
9060817df08SDavid Ahern 		signal(SIGTERM, SIG_DFL);
9070817df08SDavid Ahern 
90835b9d88eSArnaldo Carvalho de Melo 		close(child_ready_pipe[0]);
90935b9d88eSArnaldo Carvalho de Melo 		close(go_pipe[1]);
91035b9d88eSArnaldo Carvalho de Melo 		fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
91135b9d88eSArnaldo Carvalho de Melo 
91235b9d88eSArnaldo Carvalho de Melo 		/*
91335b9d88eSArnaldo Carvalho de Melo 		 * Tell the parent we're ready to go
91435b9d88eSArnaldo Carvalho de Melo 		 */
91535b9d88eSArnaldo Carvalho de Melo 		close(child_ready_pipe[1]);
91635b9d88eSArnaldo Carvalho de Melo 
91735b9d88eSArnaldo Carvalho de Melo 		/*
91835b9d88eSArnaldo Carvalho de Melo 		 * Wait until the parent tells us to go.
91935b9d88eSArnaldo Carvalho de Melo 		 */
92035b9d88eSArnaldo Carvalho de Melo 		if (read(go_pipe[0], &bf, 1) == -1)
92135b9d88eSArnaldo Carvalho de Melo 			perror("unable to read pipe");
92235b9d88eSArnaldo Carvalho de Melo 
92335b9d88eSArnaldo Carvalho de Melo 		execvp(argv[0], (char **)argv);
92435b9d88eSArnaldo Carvalho de Melo 
92535b9d88eSArnaldo Carvalho de Melo 		perror(argv[0]);
92655e162eaSNamhyung Kim 		if (want_signal)
92735b9d88eSArnaldo Carvalho de Melo 			kill(getppid(), SIGUSR1);
92835b9d88eSArnaldo Carvalho de Melo 		exit(-1);
92935b9d88eSArnaldo Carvalho de Melo 	}
93035b9d88eSArnaldo Carvalho de Melo 
9316ef73ec4SNamhyung Kim 	if (perf_target__none(target))
93235b9d88eSArnaldo Carvalho de Melo 		evlist->threads->map[0] = evlist->workload.pid;
93335b9d88eSArnaldo Carvalho de Melo 
93435b9d88eSArnaldo Carvalho de Melo 	close(child_ready_pipe[1]);
93535b9d88eSArnaldo Carvalho de Melo 	close(go_pipe[0]);
93635b9d88eSArnaldo Carvalho de Melo 	/*
93735b9d88eSArnaldo Carvalho de Melo 	 * wait for child to settle
93835b9d88eSArnaldo Carvalho de Melo 	 */
93935b9d88eSArnaldo Carvalho de Melo 	if (read(child_ready_pipe[0], &bf, 1) == -1) {
94035b9d88eSArnaldo Carvalho de Melo 		perror("unable to read pipe");
94135b9d88eSArnaldo Carvalho de Melo 		goto out_close_pipes;
94235b9d88eSArnaldo Carvalho de Melo 	}
94335b9d88eSArnaldo Carvalho de Melo 
944bcf3145fSNamhyung Kim 	fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
94535b9d88eSArnaldo Carvalho de Melo 	evlist->workload.cork_fd = go_pipe[1];
94635b9d88eSArnaldo Carvalho de Melo 	close(child_ready_pipe[0]);
94735b9d88eSArnaldo Carvalho de Melo 	return 0;
94835b9d88eSArnaldo Carvalho de Melo 
94935b9d88eSArnaldo Carvalho de Melo out_close_pipes:
95035b9d88eSArnaldo Carvalho de Melo 	close(go_pipe[0]);
95135b9d88eSArnaldo Carvalho de Melo 	close(go_pipe[1]);
95235b9d88eSArnaldo Carvalho de Melo out_close_ready_pipe:
95335b9d88eSArnaldo Carvalho de Melo 	close(child_ready_pipe[0]);
95435b9d88eSArnaldo Carvalho de Melo 	close(child_ready_pipe[1]);
95535b9d88eSArnaldo Carvalho de Melo 	return -1;
95635b9d88eSArnaldo Carvalho de Melo }
95735b9d88eSArnaldo Carvalho de Melo 
95835b9d88eSArnaldo Carvalho de Melo int perf_evlist__start_workload(struct perf_evlist *evlist)
95935b9d88eSArnaldo Carvalho de Melo {
96035b9d88eSArnaldo Carvalho de Melo 	if (evlist->workload.cork_fd > 0) {
961b3824404SDavid Ahern 		char bf = 0;
962bcf3145fSNamhyung Kim 		int ret;
96335b9d88eSArnaldo Carvalho de Melo 		/*
96435b9d88eSArnaldo Carvalho de Melo 		 * Remove the cork, let it rip!
96535b9d88eSArnaldo Carvalho de Melo 		 */
966bcf3145fSNamhyung Kim 		ret = write(evlist->workload.cork_fd, &bf, 1);
967bcf3145fSNamhyung Kim 		if (ret < 0)
968bcf3145fSNamhyung Kim 			perror("enable to write to pipe");
969bcf3145fSNamhyung Kim 
970bcf3145fSNamhyung Kim 		close(evlist->workload.cork_fd);
971bcf3145fSNamhyung Kim 		return ret;
97235b9d88eSArnaldo Carvalho de Melo 	}
97335b9d88eSArnaldo Carvalho de Melo 
97435b9d88eSArnaldo Carvalho de Melo 	return 0;
97535b9d88eSArnaldo Carvalho de Melo }
976cb0b29e0SArnaldo Carvalho de Melo 
977a3f698feSArnaldo Carvalho de Melo int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
9780807d2d8SArnaldo Carvalho de Melo 			      struct perf_sample *sample)
979cb0b29e0SArnaldo Carvalho de Melo {
98075562573SAdrian Hunter 	struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event);
98175562573SAdrian Hunter 
98275562573SAdrian Hunter 	if (!evsel)
98375562573SAdrian Hunter 		return -EFAULT;
9840807d2d8SArnaldo Carvalho de Melo 	return perf_evsel__parse_sample(evsel, event, sample);
985cb0b29e0SArnaldo Carvalho de Melo }
98678f067b3SArnaldo Carvalho de Melo 
98778f067b3SArnaldo Carvalho de Melo size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
98878f067b3SArnaldo Carvalho de Melo {
98978f067b3SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
99078f067b3SArnaldo Carvalho de Melo 	size_t printed = 0;
99178f067b3SArnaldo Carvalho de Melo 
99278f067b3SArnaldo Carvalho de Melo 	list_for_each_entry(evsel, &evlist->entries, node) {
99378f067b3SArnaldo Carvalho de Melo 		printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
99478f067b3SArnaldo Carvalho de Melo 				   perf_evsel__name(evsel));
99578f067b3SArnaldo Carvalho de Melo 	}
99678f067b3SArnaldo Carvalho de Melo 
99778f067b3SArnaldo Carvalho de Melo 	return printed + fprintf(fp, "\n");;
99878f067b3SArnaldo Carvalho de Melo }
999