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