]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - tools/perf/util/evlist.c
tools: Adopt rounddown_pow_of_two and deps
[mirror_ubuntu-bionic-kernel.git] / tools / perf / util / evlist.c
CommitLineData
f8a95309
ACM
1/*
2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3 *
4 * Parts came from builtin-{top,stat,record}.c, see those files for further
5 * copyright notes.
6 *
7 * Released under the GPL v2. (and only v2, not any later version)
8 */
a8c9ae18 9#include "util.h"
553873e1 10#include <api/fs/debugfs.h>
956fa571 11#include <api/fs/fs.h>
5c581041 12#include <poll.h>
f8a95309
ACM
13#include "cpumap.h"
14#include "thread_map.h"
12864b31 15#include "target.h"
361c99a6
ACM
16#include "evlist.h"
17#include "evsel.h"
e3e1a54f 18#include "debug.h"
35b9d88e 19#include <unistd.h>
361c99a6 20
50d08e47 21#include "parse-events.h"
994a1f78 22#include "parse-options.h"
50d08e47 23
f8a95309
ACM
24#include <sys/mman.h>
25
70db7533
ACM
26#include <linux/bitops.h>
27#include <linux/hash.h>
0389cd1f 28#include <linux/log2.h>
70db7533 29
e4b356b5
ACM
30static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
31static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
32
f8a95309 33#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
a91e5431 34#define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
f8a95309 35
7e2ed097
ACM
36void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
37 struct thread_map *threads)
ef1d1af2
ACM
38{
39 int i;
40
41 for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
42 INIT_HLIST_HEAD(&evlist->heads[i]);
43 INIT_LIST_HEAD(&evlist->entries);
7e2ed097 44 perf_evlist__set_maps(evlist, cpus, threads);
1b85337d 45 fdarray__init(&evlist->pollfd, 64);
35b9d88e 46 evlist->workload.pid = -1;
ef1d1af2
ACM
47}
48
334fe7a3 49struct perf_evlist *perf_evlist__new(void)
361c99a6
ACM
50{
51 struct perf_evlist *evlist = zalloc(sizeof(*evlist));
52
ef1d1af2 53 if (evlist != NULL)
334fe7a3 54 perf_evlist__init(evlist, NULL, NULL);
361c99a6
ACM
55
56 return evlist;
57}
58
b22d54b0
JO
59struct perf_evlist *perf_evlist__new_default(void)
60{
61 struct perf_evlist *evlist = perf_evlist__new();
62
63 if (evlist && perf_evlist__add_default(evlist)) {
64 perf_evlist__delete(evlist);
65 evlist = NULL;
66 }
67
68 return evlist;
69}
70
75562573
AH
71/**
72 * perf_evlist__set_id_pos - set the positions of event ids.
73 * @evlist: selected event list
74 *
75 * Events with compatible sample types all have the same id_pos
76 * and is_pos. For convenience, put a copy on evlist.
77 */
78void perf_evlist__set_id_pos(struct perf_evlist *evlist)
79{
80 struct perf_evsel *first = perf_evlist__first(evlist);
81
82 evlist->id_pos = first->id_pos;
83 evlist->is_pos = first->is_pos;
84}
85
733cd2fe
AH
86static void perf_evlist__update_id_pos(struct perf_evlist *evlist)
87{
88 struct perf_evsel *evsel;
89
0050f7aa 90 evlist__for_each(evlist, evsel)
733cd2fe
AH
91 perf_evsel__calc_id_pos(evsel);
92
93 perf_evlist__set_id_pos(evlist);
94}
95
361c99a6
ACM
96static void perf_evlist__purge(struct perf_evlist *evlist)
97{
98 struct perf_evsel *pos, *n;
99
0050f7aa 100 evlist__for_each_safe(evlist, n, pos) {
361c99a6
ACM
101 list_del_init(&pos->node);
102 perf_evsel__delete(pos);
103 }
104
105 evlist->nr_entries = 0;
106}
107
ef1d1af2 108void perf_evlist__exit(struct perf_evlist *evlist)
361c99a6 109{
04662523 110 zfree(&evlist->mmap);
1b85337d 111 fdarray__exit(&evlist->pollfd);
ef1d1af2
ACM
112}
113
114void perf_evlist__delete(struct perf_evlist *evlist)
115{
983874d1 116 perf_evlist__munmap(evlist);
f26e1c7c 117 perf_evlist__close(evlist);
03ad9747
ACM
118 cpu_map__delete(evlist->cpus);
119 thread_map__delete(evlist->threads);
120 evlist->cpus = NULL;
121 evlist->threads = NULL;
ef1d1af2
ACM
122 perf_evlist__purge(evlist);
123 perf_evlist__exit(evlist);
361c99a6
ACM
124 free(evlist);
125}
126
127void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
128{
129 list_add_tail(&entry->node, &evlist->entries);
ef503831 130 entry->idx = evlist->nr_entries;
60b0896c 131 entry->tracking = !entry->idx;
ef503831 132
75562573
AH
133 if (!evlist->nr_entries++)
134 perf_evlist__set_id_pos(evlist);
361c99a6
ACM
135}
136
0529bc1f
JO
137void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
138 struct list_head *list,
139 int nr_entries)
50d08e47 140{
75562573
AH
141 bool set_id_pos = !evlist->nr_entries;
142
50d08e47
ACM
143 list_splice_tail(list, &evlist->entries);
144 evlist->nr_entries += nr_entries;
75562573
AH
145 if (set_id_pos)
146 perf_evlist__set_id_pos(evlist);
50d08e47
ACM
147}
148
63dab225
ACM
149void __perf_evlist__set_leader(struct list_head *list)
150{
151 struct perf_evsel *evsel, *leader;
152
153 leader = list_entry(list->next, struct perf_evsel, node);
97f63e4a
NK
154 evsel = list_entry(list->prev, struct perf_evsel, node);
155
156 leader->nr_members = evsel->idx - leader->idx + 1;
63dab225 157
0050f7aa 158 __evlist__for_each(list, evsel) {
74b2133d 159 evsel->leader = leader;
63dab225
ACM
160 }
161}
162
163void perf_evlist__set_leader(struct perf_evlist *evlist)
6a4bb04c 164{
97f63e4a
NK
165 if (evlist->nr_entries) {
166 evlist->nr_groups = evlist->nr_entries > 1 ? 1 : 0;
63dab225 167 __perf_evlist__set_leader(&evlist->entries);
97f63e4a 168 }
6a4bb04c
JO
169}
170
361c99a6
ACM
171int perf_evlist__add_default(struct perf_evlist *evlist)
172{
173 struct perf_event_attr attr = {
174 .type = PERF_TYPE_HARDWARE,
175 .config = PERF_COUNT_HW_CPU_CYCLES,
176 };
1aed2671
JR
177 struct perf_evsel *evsel;
178
179 event_attr_init(&attr);
361c99a6 180
ef503831 181 evsel = perf_evsel__new(&attr);
361c99a6 182 if (evsel == NULL)
cc2d86b0
SE
183 goto error;
184
185 /* use strdup() because free(evsel) assumes name is allocated */
186 evsel->name = strdup("cycles");
187 if (!evsel->name)
188 goto error_free;
361c99a6
ACM
189
190 perf_evlist__add(evlist, evsel);
191 return 0;
cc2d86b0
SE
192error_free:
193 perf_evsel__delete(evsel);
194error:
195 return -ENOMEM;
361c99a6 196}
5c581041 197
e60fc847
ACM
198static int perf_evlist__add_attrs(struct perf_evlist *evlist,
199 struct perf_event_attr *attrs, size_t nr_attrs)
50d08e47
ACM
200{
201 struct perf_evsel *evsel, *n;
202 LIST_HEAD(head);
203 size_t i;
204
205 for (i = 0; i < nr_attrs; i++) {
ef503831 206 evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i);
50d08e47
ACM
207 if (evsel == NULL)
208 goto out_delete_partial_list;
209 list_add_tail(&evsel->node, &head);
210 }
211
212 perf_evlist__splice_list_tail(evlist, &head, nr_attrs);
213
214 return 0;
215
216out_delete_partial_list:
0050f7aa 217 __evlist__for_each_safe(&head, n, evsel)
50d08e47
ACM
218 perf_evsel__delete(evsel);
219 return -1;
220}
221
79695e1b
ACM
222int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
223 struct perf_event_attr *attrs, size_t nr_attrs)
224{
225 size_t i;
226
227 for (i = 0; i < nr_attrs; i++)
228 event_attr_init(attrs + i);
229
230 return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
231}
232
da378962
ACM
233struct perf_evsel *
234perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
ee29be62
ACM
235{
236 struct perf_evsel *evsel;
237
0050f7aa 238 evlist__for_each(evlist, evsel) {
ee29be62
ACM
239 if (evsel->attr.type == PERF_TYPE_TRACEPOINT &&
240 (int)evsel->attr.config == id)
241 return evsel;
242 }
243
244 return NULL;
245}
246
a2f2804a
DA
247struct perf_evsel *
248perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
249 const char *name)
250{
251 struct perf_evsel *evsel;
252
0050f7aa 253 evlist__for_each(evlist, evsel) {
a2f2804a
DA
254 if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) &&
255 (strcmp(evsel->name, name) == 0))
256 return evsel;
257 }
258
259 return NULL;
260}
261
39876e7d
ACM
262int perf_evlist__add_newtp(struct perf_evlist *evlist,
263 const char *sys, const char *name, void *handler)
264{
ef503831 265 struct perf_evsel *evsel = perf_evsel__newtp(sys, name);
39876e7d 266
39876e7d
ACM
267 if (evsel == NULL)
268 return -1;
269
744a9719 270 evsel->handler = handler;
39876e7d
ACM
271 perf_evlist__add(evlist, evsel);
272 return 0;
273}
274
bf8e8f4b
AH
275static int perf_evlist__nr_threads(struct perf_evlist *evlist,
276 struct perf_evsel *evsel)
277{
278 if (evsel->system_wide)
279 return 1;
280 else
281 return thread_map__nr(evlist->threads);
282}
283
4152ab37
ACM
284void perf_evlist__disable(struct perf_evlist *evlist)
285{
286 int cpu, thread;
287 struct perf_evsel *pos;
b3a319d5 288 int nr_cpus = cpu_map__nr(evlist->cpus);
bf8e8f4b 289 int nr_threads;
4152ab37 290
b3a319d5 291 for (cpu = 0; cpu < nr_cpus; cpu++) {
0050f7aa 292 evlist__for_each(evlist, pos) {
395c3070 293 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
3fe4430d 294 continue;
bf8e8f4b 295 nr_threads = perf_evlist__nr_threads(evlist, pos);
b3a319d5 296 for (thread = 0; thread < nr_threads; thread++)
55da8005
NK
297 ioctl(FD(pos, cpu, thread),
298 PERF_EVENT_IOC_DISABLE, 0);
4152ab37
ACM
299 }
300 }
301}
302
764e16a3
DA
303void perf_evlist__enable(struct perf_evlist *evlist)
304{
305 int cpu, thread;
306 struct perf_evsel *pos;
b3a319d5 307 int nr_cpus = cpu_map__nr(evlist->cpus);
bf8e8f4b 308 int nr_threads;
764e16a3 309
b3a319d5 310 for (cpu = 0; cpu < nr_cpus; cpu++) {
0050f7aa 311 evlist__for_each(evlist, pos) {
395c3070 312 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
3fe4430d 313 continue;
bf8e8f4b 314 nr_threads = perf_evlist__nr_threads(evlist, pos);
b3a319d5 315 for (thread = 0; thread < nr_threads; thread++)
55da8005
NK
316 ioctl(FD(pos, cpu, thread),
317 PERF_EVENT_IOC_ENABLE, 0);
764e16a3
DA
318 }
319 }
320}
321
395c3070
AH
322int perf_evlist__disable_event(struct perf_evlist *evlist,
323 struct perf_evsel *evsel)
324{
325 int cpu, thread, err;
bf8e8f4b
AH
326 int nr_cpus = cpu_map__nr(evlist->cpus);
327 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
395c3070
AH
328
329 if (!evsel->fd)
330 return 0;
331
bf8e8f4b
AH
332 for (cpu = 0; cpu < nr_cpus; cpu++) {
333 for (thread = 0; thread < nr_threads; thread++) {
395c3070
AH
334 err = ioctl(FD(evsel, cpu, thread),
335 PERF_EVENT_IOC_DISABLE, 0);
336 if (err)
337 return err;
338 }
339 }
340 return 0;
341}
342
343int perf_evlist__enable_event(struct perf_evlist *evlist,
344 struct perf_evsel *evsel)
345{
346 int cpu, thread, err;
bf8e8f4b
AH
347 int nr_cpus = cpu_map__nr(evlist->cpus);
348 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
395c3070
AH
349
350 if (!evsel->fd)
351 return -EINVAL;
352
bf8e8f4b
AH
353 for (cpu = 0; cpu < nr_cpus; cpu++) {
354 for (thread = 0; thread < nr_threads; thread++) {
395c3070
AH
355 err = ioctl(FD(evsel, cpu, thread),
356 PERF_EVENT_IOC_ENABLE, 0);
357 if (err)
358 return err;
359 }
360 }
361 return 0;
362}
363
1c65056c
AH
364static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist,
365 struct perf_evsel *evsel, int cpu)
366{
367 int thread, err;
368 int nr_threads = perf_evlist__nr_threads(evlist, evsel);
369
370 if (!evsel->fd)
371 return -EINVAL;
372
373 for (thread = 0; thread < nr_threads; thread++) {
374 err = ioctl(FD(evsel, cpu, thread),
375 PERF_EVENT_IOC_ENABLE, 0);
376 if (err)
377 return err;
378 }
379 return 0;
380}
381
382static int perf_evlist__enable_event_thread(struct perf_evlist *evlist,
383 struct perf_evsel *evsel,
384 int thread)
385{
386 int cpu, err;
387 int nr_cpus = cpu_map__nr(evlist->cpus);
388
389 if (!evsel->fd)
390 return -EINVAL;
391
392 for (cpu = 0; cpu < nr_cpus; cpu++) {
393 err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0);
394 if (err)
395 return err;
396 }
397 return 0;
398}
399
400int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
401 struct perf_evsel *evsel, int idx)
402{
403 bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus);
404
405 if (per_cpu_mmaps)
406 return perf_evlist__enable_event_cpu(evlist, evsel, idx);
407 else
408 return perf_evlist__enable_event_thread(evlist, evsel, idx);
409}
410
ad6765dd 411int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
5c581041 412{
b3a319d5
NK
413 int nr_cpus = cpu_map__nr(evlist->cpus);
414 int nr_threads = thread_map__nr(evlist->threads);
bf8e8f4b
AH
415 int nfds = 0;
416 struct perf_evsel *evsel;
417
cba9b847 418 evlist__for_each(evlist, evsel) {
bf8e8f4b
AH
419 if (evsel->system_wide)
420 nfds += nr_cpus;
421 else
422 nfds += nr_cpus * nr_threads;
423 }
424
1b85337d
ACM
425 if (fdarray__available_entries(&evlist->pollfd) < nfds &&
426 fdarray__grow(&evlist->pollfd, nfds) < 0)
ad6765dd
ACM
427 return -ENOMEM;
428
429 return 0;
5c581041 430}
70082dd9 431
e4b356b5
ACM
432static int __perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd, int idx)
433{
434 int pos = fdarray__add(&evlist->pollfd, fd, POLLIN | POLLERR | POLLHUP);
435 /*
436 * Save the idx so that when we filter out fds POLLHUP'ed we can
437 * close the associated evlist->mmap[] entry.
438 */
439 if (pos >= 0) {
440 evlist->pollfd.priv[pos].idx = idx;
441
442 fcntl(fd, F_SETFL, O_NONBLOCK);
443 }
444
445 return pos;
446}
447
ad6765dd 448int perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
70082dd9 449{
e4b356b5
ACM
450 return __perf_evlist__add_pollfd(evlist, fd, -1);
451}
452
453static void perf_evlist__munmap_filtered(struct fdarray *fda, int fd)
454{
455 struct perf_evlist *evlist = container_of(fda, struct perf_evlist, pollfd);
1b85337d 456
e4b356b5 457 perf_evlist__mmap_put(evlist, fda->priv[fd].idx);
70082dd9 458}
70db7533 459
1ddec7f0
ACM
460int perf_evlist__filter_pollfd(struct perf_evlist *evlist, short revents_and_mask)
461{
e4b356b5
ACM
462 return fdarray__filter(&evlist->pollfd, revents_and_mask,
463 perf_evlist__munmap_filtered);
1ddec7f0
ACM
464}
465
f66a889d
ACM
466int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
467{
1b85337d 468 return fdarray__poll(&evlist->pollfd, timeout);
f66a889d
ACM
469}
470
a91e5431
ACM
471static void perf_evlist__id_hash(struct perf_evlist *evlist,
472 struct perf_evsel *evsel,
473 int cpu, int thread, u64 id)
3d3b5e95
ACM
474{
475 int hash;
476 struct perf_sample_id *sid = SID(evsel, cpu, thread);
477
478 sid->id = id;
479 sid->evsel = evsel;
480 hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
481 hlist_add_head(&sid->node, &evlist->heads[hash]);
482}
483
a91e5431
ACM
484void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
485 int cpu, int thread, u64 id)
486{
487 perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
488 evsel->id[evsel->ids++] = id;
489}
490
491static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
492 struct perf_evsel *evsel,
493 int cpu, int thread, int fd)
f8a95309 494{
f8a95309 495 u64 read_data[4] = { 0, };
3d3b5e95 496 int id_idx = 1; /* The first entry is the counter value */
e2b5abe0
JO
497 u64 id;
498 int ret;
499
500 ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
501 if (!ret)
502 goto add;
503
504 if (errno != ENOTTY)
505 return -1;
506
507 /* Legacy way to get event id.. All hail to old kernels! */
f8a95309 508
c4861afe
JO
509 /*
510 * This way does not work with group format read, so bail
511 * out in that case.
512 */
513 if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP)
514 return -1;
515
f8a95309
ACM
516 if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
517 read(fd, &read_data, sizeof(read_data)) == -1)
518 return -1;
519
520 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
521 ++id_idx;
522 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
523 ++id_idx;
524
e2b5abe0
JO
525 id = read_data[id_idx];
526
527 add:
528 perf_evlist__id_add(evlist, evsel, cpu, thread, id);
f8a95309
ACM
529 return 0;
530}
531
3c659eed
AH
532static void perf_evlist__set_sid_idx(struct perf_evlist *evlist,
533 struct perf_evsel *evsel, int idx, int cpu,
534 int thread)
535{
536 struct perf_sample_id *sid = SID(evsel, cpu, thread);
537 sid->idx = idx;
538 if (evlist->cpus && cpu >= 0)
539 sid->cpu = evlist->cpus->map[cpu];
540 else
541 sid->cpu = -1;
542 if (!evsel->system_wide && evlist->threads && thread >= 0)
543 sid->tid = evlist->threads->map[thread];
544 else
545 sid->tid = -1;
546}
547
932a3594 548struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id)
70db7533
ACM
549{
550 struct hlist_head *head;
70db7533
ACM
551 struct perf_sample_id *sid;
552 int hash;
553
70db7533
ACM
554 hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
555 head = &evlist->heads[hash];
556
b67bfe0d 557 hlist_for_each_entry(sid, head, node)
70db7533 558 if (sid->id == id)
932a3594
JO
559 return sid;
560
561 return NULL;
562}
563
564struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
565{
566 struct perf_sample_id *sid;
567
568 if (evlist->nr_entries == 1)
569 return perf_evlist__first(evlist);
570
571 sid = perf_evlist__id2sid(evlist, id);
572 if (sid)
573 return sid->evsel;
30e68bcc
NK
574
575 if (!perf_evlist__sample_id_all(evlist))
0c21f736 576 return perf_evlist__first(evlist);
30e68bcc 577
70db7533
ACM
578 return NULL;
579}
04391deb 580
75562573
AH
581static int perf_evlist__event2id(struct perf_evlist *evlist,
582 union perf_event *event, u64 *id)
583{
584 const u64 *array = event->sample.array;
585 ssize_t n;
586
587 n = (event->header.size - sizeof(event->header)) >> 3;
588
589 if (event->header.type == PERF_RECORD_SAMPLE) {
590 if (evlist->id_pos >= n)
591 return -1;
592 *id = array[evlist->id_pos];
593 } else {
594 if (evlist->is_pos > n)
595 return -1;
596 n -= evlist->is_pos;
597 *id = array[n];
598 }
599 return 0;
600}
601
602static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
603 union perf_event *event)
604{
98be6966 605 struct perf_evsel *first = perf_evlist__first(evlist);
75562573
AH
606 struct hlist_head *head;
607 struct perf_sample_id *sid;
608 int hash;
609 u64 id;
610
611 if (evlist->nr_entries == 1)
98be6966
AH
612 return first;
613
614 if (!first->attr.sample_id_all &&
615 event->header.type != PERF_RECORD_SAMPLE)
616 return first;
75562573
AH
617
618 if (perf_evlist__event2id(evlist, event, &id))
619 return NULL;
620
621 /* Synthesized events have an id of zero */
622 if (!id)
98be6966 623 return first;
75562573
AH
624
625 hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
626 head = &evlist->heads[hash];
627
628 hlist_for_each_entry(sid, head, node) {
629 if (sid->id == id)
630 return sid->evsel;
631 }
632 return NULL;
633}
634
aece948f 635union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
04391deb 636{
aece948f 637 struct perf_mmap *md = &evlist->mmap[idx];
04391deb
ACM
638 unsigned int head = perf_mmap__read_head(md);
639 unsigned int old = md->prev;
640 unsigned char *data = md->base + page_size;
8115d60c 641 union perf_event *event = NULL;
04391deb 642
7bb41152 643 if (evlist->overwrite) {
04391deb 644 /*
7bb41152
ACM
645 * If we're further behind than half the buffer, there's a chance
646 * the writer will bite our tail and mess up the samples under us.
647 *
648 * If we somehow ended up ahead of the head, we got messed up.
649 *
650 * In either case, truncate and restart at head.
04391deb 651 */
7bb41152
ACM
652 int diff = head - old;
653 if (diff > md->mask / 2 || diff < 0) {
654 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
655
656 /*
657 * head points to a known good entry, start there.
658 */
659 old = head;
660 }
04391deb
ACM
661 }
662
663 if (old != head) {
664 size_t size;
665
8115d60c 666 event = (union perf_event *)&data[old & md->mask];
04391deb
ACM
667 size = event->header.size;
668
669 /*
670 * Event straddles the mmap boundary -- header should always
671 * be inside due to u64 alignment of output.
672 */
673 if ((old & md->mask) + size != ((old + size) & md->mask)) {
674 unsigned int offset = old;
675 unsigned int len = min(sizeof(*event), size), cpy;
a65cb4b9 676 void *dst = md->event_copy;
04391deb
ACM
677
678 do {
679 cpy = min(md->mask + 1 - (offset & md->mask), len);
680 memcpy(dst, &data[offset & md->mask], cpy);
681 offset += cpy;
682 dst += cpy;
683 len -= cpy;
684 } while (len);
685
a65cb4b9 686 event = (union perf_event *) md->event_copy;
04391deb
ACM
687 }
688
689 old += size;
690 }
691
692 md->prev = old;
7bb41152 693
04391deb
ACM
694 return event;
695}
f8a95309 696
82396986
ACM
697static bool perf_mmap__empty(struct perf_mmap *md)
698{
699 return perf_mmap__read_head(md) != md->prev;
700}
701
702static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)
703{
704 ++evlist->mmap[idx].refcnt;
705}
706
707static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx)
708{
709 BUG_ON(evlist->mmap[idx].refcnt == 0);
710
711 if (--evlist->mmap[idx].refcnt == 0)
712 __perf_evlist__munmap(evlist, idx);
713}
714
8e50d384
ZZ
715void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx)
716{
82396986
ACM
717 struct perf_mmap *md = &evlist->mmap[idx];
718
8e50d384 719 if (!evlist->overwrite) {
8e50d384
ZZ
720 unsigned int old = md->prev;
721
722 perf_mmap__write_tail(md, old);
723 }
82396986
ACM
724
725 if (md->refcnt == 1 && perf_mmap__empty(md))
726 perf_evlist__mmap_put(evlist, idx);
8e50d384
ZZ
727}
728
93edcbd9
AH
729static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx)
730{
731 if (evlist->mmap[idx].base != NULL) {
732 munmap(evlist->mmap[idx].base, evlist->mmap_len);
733 evlist->mmap[idx].base = NULL;
82396986 734 evlist->mmap[idx].refcnt = 0;
93edcbd9
AH
735 }
736}
737
7e2ed097 738void perf_evlist__munmap(struct perf_evlist *evlist)
f8a95309 739{
aece948f 740 int i;
f8a95309 741
983874d1
ACM
742 if (evlist->mmap == NULL)
743 return;
744
93edcbd9
AH
745 for (i = 0; i < evlist->nr_mmaps; i++)
746 __perf_evlist__munmap(evlist, i);
aece948f 747
04662523 748 zfree(&evlist->mmap);
f8a95309
ACM
749}
750
806fb630 751static int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
f8a95309 752{
a14bb7a6 753 evlist->nr_mmaps = cpu_map__nr(evlist->cpus);
ec1e7e43 754 if (cpu_map__empty(evlist->cpus))
b3a319d5 755 evlist->nr_mmaps = thread_map__nr(evlist->threads);
aece948f 756 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
f8a95309
ACM
757 return evlist->mmap != NULL ? 0 : -ENOMEM;
758}
759
a8a8f3eb
AH
760struct mmap_params {
761 int prot;
762 int mask;
763};
764
765static int __perf_evlist__mmap(struct perf_evlist *evlist, int idx,
766 struct mmap_params *mp, int fd)
f8a95309 767{
82396986
ACM
768 /*
769 * The last one will be done at perf_evlist__mmap_consume(), so that we
770 * make sure we don't prevent tools from consuming every last event in
771 * the ring buffer.
772 *
773 * I.e. we can get the POLLHUP meaning that the fd doesn't exist
774 * anymore, but the last events for it are still in the ring buffer,
775 * waiting to be consumed.
776 *
777 * Tools can chose to ignore this at their own discretion, but the
778 * evlist layer can't just drop it when filtering events in
779 * perf_evlist__filter_pollfd().
780 */
781 evlist->mmap[idx].refcnt = 2;
aece948f 782 evlist->mmap[idx].prev = 0;
a8a8f3eb
AH
783 evlist->mmap[idx].mask = mp->mask;
784 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, mp->prot,
f8a95309 785 MAP_SHARED, fd, 0);
301b195d 786 if (evlist->mmap[idx].base == MAP_FAILED) {
02635965
AH
787 pr_debug2("failed to mmap perf event ring buffer, error %d\n",
788 errno);
301b195d 789 evlist->mmap[idx].base = NULL;
f8a95309 790 return -1;
301b195d 791 }
ad6765dd 792
f8a95309
ACM
793 return 0;
794}
795
04e21314 796static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
a8a8f3eb
AH
797 struct mmap_params *mp, int cpu,
798 int thread, int *output)
aece948f
ACM
799{
800 struct perf_evsel *evsel;
04e21314 801
0050f7aa 802 evlist__for_each(evlist, evsel) {
bf8e8f4b
AH
803 int fd;
804
805 if (evsel->system_wide && thread)
806 continue;
807
808 fd = FD(evsel, cpu, thread);
04e21314
AH
809
810 if (*output == -1) {
811 *output = fd;
a8a8f3eb 812 if (__perf_evlist__mmap(evlist, idx, mp, *output) < 0)
04e21314
AH
813 return -1;
814 } else {
815 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, *output) != 0)
816 return -1;
82396986
ACM
817
818 perf_evlist__mmap_get(evlist, idx);
04e21314
AH
819 }
820
f90d194a
AH
821 /*
822 * The system_wide flag causes a selected event to be opened
823 * always without a pid. Consequently it will never get a
824 * POLLHUP, but it is used for tracking in combination with
825 * other events, so it should not need to be polled anyway.
826 * Therefore don't add it for polling.
827 */
828 if (!evsel->system_wide &&
829 __perf_evlist__add_pollfd(evlist, fd, idx) < 0) {
82396986 830 perf_evlist__mmap_put(evlist, idx);
ad6765dd 831 return -1;
82396986 832 }
033fa713 833
3c659eed
AH
834 if (evsel->attr.read_format & PERF_FORMAT_ID) {
835 if (perf_evlist__id_add_fd(evlist, evsel, cpu, thread,
836 fd) < 0)
837 return -1;
838 perf_evlist__set_sid_idx(evlist, evsel, idx, cpu,
839 thread);
840 }
04e21314
AH
841 }
842
843 return 0;
844}
845
a8a8f3eb
AH
846static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist,
847 struct mmap_params *mp)
04e21314 848{
aece948f 849 int cpu, thread;
b3a319d5
NK
850 int nr_cpus = cpu_map__nr(evlist->cpus);
851 int nr_threads = thread_map__nr(evlist->threads);
aece948f 852
e3e1a54f 853 pr_debug2("perf event ring buffer mmapped per cpu\n");
b3a319d5 854 for (cpu = 0; cpu < nr_cpus; cpu++) {
aece948f
ACM
855 int output = -1;
856
b3a319d5 857 for (thread = 0; thread < nr_threads; thread++) {
a8a8f3eb
AH
858 if (perf_evlist__mmap_per_evsel(evlist, cpu, mp, cpu,
859 thread, &output))
04e21314 860 goto out_unmap;
aece948f
ACM
861 }
862 }
863
864 return 0;
865
866out_unmap:
93edcbd9
AH
867 for (cpu = 0; cpu < nr_cpus; cpu++)
868 __perf_evlist__munmap(evlist, cpu);
aece948f
ACM
869 return -1;
870}
871
a8a8f3eb
AH
872static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist,
873 struct mmap_params *mp)
aece948f 874{
aece948f 875 int thread;
b3a319d5 876 int nr_threads = thread_map__nr(evlist->threads);
aece948f 877
e3e1a54f 878 pr_debug2("perf event ring buffer mmapped per thread\n");
b3a319d5 879 for (thread = 0; thread < nr_threads; thread++) {
aece948f
ACM
880 int output = -1;
881
a8a8f3eb
AH
882 if (perf_evlist__mmap_per_evsel(evlist, thread, mp, 0, thread,
883 &output))
04e21314 884 goto out_unmap;
aece948f
ACM
885 }
886
887 return 0;
888
889out_unmap:
93edcbd9
AH
890 for (thread = 0; thread < nr_threads; thread++)
891 __perf_evlist__munmap(evlist, thread);
aece948f
ACM
892 return -1;
893}
894
994a1f78
JO
895static size_t perf_evlist__mmap_size(unsigned long pages)
896{
8185e881
ACM
897 if (pages == UINT_MAX) {
898 int max;
899
900 if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
901 /*
902 * Pick a once upon a time good value, i.e. things look
903 * strange since we can't read a sysctl value, but lets not
904 * die yet...
905 */
906 max = 512;
907 } else {
908 max -= (page_size / 1024);
909 }
910
911 pages = (max * 1024) / page_size;
912 } else if (!is_power_of_2(pages))
994a1f78
JO
913 return 0;
914
915 return (pages + 1) * page_size;
916}
917
33c2dcfd
DA
918static long parse_pages_arg(const char *str, unsigned long min,
919 unsigned long max)
994a1f78 920{
2fbe4abe 921 unsigned long pages, val;
27050f53
JO
922 static struct parse_tag tags[] = {
923 { .tag = 'B', .mult = 1 },
924 { .tag = 'K', .mult = 1 << 10 },
925 { .tag = 'M', .mult = 1 << 20 },
926 { .tag = 'G', .mult = 1 << 30 },
927 { .tag = 0 },
928 };
994a1f78 929
8973504b 930 if (str == NULL)
33c2dcfd 931 return -EINVAL;
8973504b 932
27050f53 933 val = parse_tag_value(str, tags);
2fbe4abe 934 if (val != (unsigned long) -1) {
27050f53
JO
935 /* we got file size value */
936 pages = PERF_ALIGN(val, page_size) / page_size;
27050f53
JO
937 } else {
938 /* we got pages count value */
939 char *eptr;
940 pages = strtoul(str, &eptr, 10);
33c2dcfd
DA
941 if (*eptr != '\0')
942 return -EINVAL;
994a1f78
JO
943 }
944
2bcab6c1 945 if (pages == 0 && min == 0) {
33c2dcfd 946 /* leave number of pages at 0 */
1dbfa938 947 } else if (!is_power_of_2(pages)) {
33c2dcfd 948 /* round pages up to next power of 2 */
1dbfa938
AH
949 pages = next_pow2_l(pages);
950 if (!pages)
951 return -EINVAL;
9639837e
DA
952 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
953 pages * page_size, pages);
2fbe4abe
AH
954 }
955
33c2dcfd
DA
956 if (pages > max)
957 return -EINVAL;
958
959 return pages;
960}
961
962int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
963 int unset __maybe_unused)
964{
965 unsigned int *mmap_pages = opt->value;
966 unsigned long max = UINT_MAX;
967 long pages;
968
f5ae9c42 969 if (max > SIZE_MAX / page_size)
33c2dcfd
DA
970 max = SIZE_MAX / page_size;
971
972 pages = parse_pages_arg(str, 1, max);
973 if (pages < 0) {
974 pr_err("Invalid argument for --mmap_pages/-m\n");
994a1f78
JO
975 return -1;
976 }
977
978 *mmap_pages = pages;
979 return 0;
980}
981
c83fa7f2
AH
982/**
983 * perf_evlist__mmap - Create mmaps to receive events.
984 * @evlist: list of events
985 * @pages: map length in pages
986 * @overwrite: overwrite older events?
f8a95309 987 *
c83fa7f2
AH
988 * If @overwrite is %false the user needs to signal event consumption using
989 * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this
990 * automatically.
7e2ed097 991 *
c83fa7f2 992 * Return: %0 on success, negative error code otherwise.
f8a95309 993 */
50a682ce
ACM
994int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
995 bool overwrite)
f8a95309 996{
aece948f 997 struct perf_evsel *evsel;
7e2ed097
ACM
998 const struct cpu_map *cpus = evlist->cpus;
999 const struct thread_map *threads = evlist->threads;
a8a8f3eb
AH
1000 struct mmap_params mp = {
1001 .prot = PROT_READ | (overwrite ? 0 : PROT_WRITE),
1002 };
50a682ce 1003
7e2ed097 1004 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
f8a95309
ACM
1005 return -ENOMEM;
1006
1b85337d 1007 if (evlist->pollfd.entries == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
f8a95309
ACM
1008 return -ENOMEM;
1009
1010 evlist->overwrite = overwrite;
994a1f78 1011 evlist->mmap_len = perf_evlist__mmap_size(pages);
2af68ef5 1012 pr_debug("mmap size %zuB\n", evlist->mmap_len);
a8a8f3eb 1013 mp.mask = evlist->mmap_len - page_size - 1;
f8a95309 1014
0050f7aa 1015 evlist__for_each(evlist, evsel) {
f8a95309 1016 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
a91e5431 1017 evsel->sample_id == NULL &&
a14bb7a6 1018 perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0)
f8a95309 1019 return -ENOMEM;
f8a95309
ACM
1020 }
1021
ec1e7e43 1022 if (cpu_map__empty(cpus))
a8a8f3eb 1023 return perf_evlist__mmap_per_thread(evlist, &mp);
f8a95309 1024
a8a8f3eb 1025 return perf_evlist__mmap_per_cpu(evlist, &mp);
f8a95309 1026}
7e2ed097 1027
602ad878 1028int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
7e2ed097 1029{
b809ac10
NK
1030 evlist->threads = thread_map__new_str(target->pid, target->tid,
1031 target->uid);
7e2ed097
ACM
1032
1033 if (evlist->threads == NULL)
1034 return -1;
1035
9c105fbc 1036 if (target__uses_dummy_map(target))
d1cb9fce 1037 evlist->cpus = cpu_map__dummy_new();
879d77d0
NK
1038 else
1039 evlist->cpus = cpu_map__new(target->cpu_list);
7e2ed097
ACM
1040
1041 if (evlist->cpus == NULL)
1042 goto out_delete_threads;
1043
1044 return 0;
1045
1046out_delete_threads:
1047 thread_map__delete(evlist->threads);
b2e19a93 1048 evlist->threads = NULL;
7e2ed097
ACM
1049 return -1;
1050}
1051
1491a632 1052int perf_evlist__apply_filters(struct perf_evlist *evlist)
0a102479 1053{
0a102479 1054 struct perf_evsel *evsel;
745cefc5
ACM
1055 int err = 0;
1056 const int ncpus = cpu_map__nr(evlist->cpus),
b3a319d5 1057 nthreads = thread_map__nr(evlist->threads);
0a102479 1058
0050f7aa 1059 evlist__for_each(evlist, evsel) {
745cefc5 1060 if (evsel->filter == NULL)
0a102479 1061 continue;
745cefc5
ACM
1062
1063 err = perf_evsel__set_filter(evsel, ncpus, nthreads, evsel->filter);
1064 if (err)
1065 break;
0a102479
FW
1066 }
1067
745cefc5
ACM
1068 return err;
1069}
1070
1071int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter)
1072{
1073 struct perf_evsel *evsel;
1074 int err = 0;
1075 const int ncpus = cpu_map__nr(evlist->cpus),
b3a319d5 1076 nthreads = thread_map__nr(evlist->threads);
745cefc5 1077
0050f7aa 1078 evlist__for_each(evlist, evsel) {
745cefc5
ACM
1079 err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter);
1080 if (err)
1081 break;
1082 }
1083
1084 return err;
0a102479 1085}
74429964 1086
0c21f736 1087bool perf_evlist__valid_sample_type(struct perf_evlist *evlist)
74429964 1088{
75562573 1089 struct perf_evsel *pos;
c2a70653 1090
75562573
AH
1091 if (evlist->nr_entries == 1)
1092 return true;
1093
1094 if (evlist->id_pos < 0 || evlist->is_pos < 0)
1095 return false;
1096
0050f7aa 1097 evlist__for_each(evlist, pos) {
75562573
AH
1098 if (pos->id_pos != evlist->id_pos ||
1099 pos->is_pos != evlist->is_pos)
c2a70653 1100 return false;
74429964
FW
1101 }
1102
c2a70653 1103 return true;
74429964
FW
1104}
1105
75562573 1106u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist)
c2a70653 1107{
75562573
AH
1108 struct perf_evsel *evsel;
1109
1110 if (evlist->combined_sample_type)
1111 return evlist->combined_sample_type;
1112
0050f7aa 1113 evlist__for_each(evlist, evsel)
75562573
AH
1114 evlist->combined_sample_type |= evsel->attr.sample_type;
1115
1116 return evlist->combined_sample_type;
1117}
1118
1119u64 perf_evlist__combined_sample_type(struct perf_evlist *evlist)
1120{
1121 evlist->combined_sample_type = 0;
1122 return __perf_evlist__combined_sample_type(evlist);
c2a70653
ACM
1123}
1124
9ede473c
JO
1125bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
1126{
1127 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
1128 u64 read_format = first->attr.read_format;
1129 u64 sample_type = first->attr.sample_type;
1130
0050f7aa 1131 evlist__for_each(evlist, pos) {
9ede473c
JO
1132 if (read_format != pos->attr.read_format)
1133 return false;
1134 }
1135
1136 /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */
1137 if ((sample_type & PERF_SAMPLE_READ) &&
1138 !(read_format & PERF_FORMAT_ID)) {
1139 return false;
1140 }
1141
1142 return true;
1143}
1144
1145u64 perf_evlist__read_format(struct perf_evlist *evlist)
1146{
1147 struct perf_evsel *first = perf_evlist__first(evlist);
1148 return first->attr.read_format;
1149}
1150
0c21f736 1151u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist)
81e36bff 1152{
0c21f736 1153 struct perf_evsel *first = perf_evlist__first(evlist);
81e36bff
ACM
1154 struct perf_sample *data;
1155 u64 sample_type;
1156 u16 size = 0;
1157
81e36bff
ACM
1158 if (!first->attr.sample_id_all)
1159 goto out;
1160
1161 sample_type = first->attr.sample_type;
1162
1163 if (sample_type & PERF_SAMPLE_TID)
1164 size += sizeof(data->tid) * 2;
1165
1166 if (sample_type & PERF_SAMPLE_TIME)
1167 size += sizeof(data->time);
1168
1169 if (sample_type & PERF_SAMPLE_ID)
1170 size += sizeof(data->id);
1171
1172 if (sample_type & PERF_SAMPLE_STREAM_ID)
1173 size += sizeof(data->stream_id);
1174
1175 if (sample_type & PERF_SAMPLE_CPU)
1176 size += sizeof(data->cpu) * 2;
75562573
AH
1177
1178 if (sample_type & PERF_SAMPLE_IDENTIFIER)
1179 size += sizeof(data->id);
81e36bff
ACM
1180out:
1181 return size;
1182}
1183
0c21f736 1184bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist)
74429964 1185{
0c21f736 1186 struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
c2a70653 1187
0050f7aa 1188 evlist__for_each_continue(evlist, pos) {
c2a70653
ACM
1189 if (first->attr.sample_id_all != pos->attr.sample_id_all)
1190 return false;
74429964
FW
1191 }
1192
c2a70653
ACM
1193 return true;
1194}
1195
0c21f736 1196bool perf_evlist__sample_id_all(struct perf_evlist *evlist)
c2a70653 1197{
0c21f736 1198 struct perf_evsel *first = perf_evlist__first(evlist);
c2a70653 1199 return first->attr.sample_id_all;
74429964 1200}
81cce8de
ACM
1201
1202void perf_evlist__set_selected(struct perf_evlist *evlist,
1203 struct perf_evsel *evsel)
1204{
1205 evlist->selected = evsel;
1206}
727ab04e 1207
a74b4b66
NK
1208void perf_evlist__close(struct perf_evlist *evlist)
1209{
1210 struct perf_evsel *evsel;
1211 int ncpus = cpu_map__nr(evlist->cpus);
1212 int nthreads = thread_map__nr(evlist->threads);
8ad9219e 1213 int n;
a74b4b66 1214
8ad9219e
SE
1215 evlist__for_each_reverse(evlist, evsel) {
1216 n = evsel->cpus ? evsel->cpus->nr : ncpus;
1217 perf_evsel__close(evsel, n, nthreads);
1218 }
a74b4b66
NK
1219}
1220
4112eb18
ACM
1221static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
1222{
1223 int err = -ENOMEM;
1224
1225 /*
1226 * Try reading /sys/devices/system/cpu/online to get
1227 * an all cpus map.
1228 *
1229 * FIXME: -ENOMEM is the best we can do here, the cpu_map
1230 * code needs an overhaul to properly forward the
1231 * error, and we may not want to do that fallback to a
1232 * default cpu identity map :-\
1233 */
1234 evlist->cpus = cpu_map__new(NULL);
1235 if (evlist->cpus == NULL)
1236 goto out;
1237
1238 evlist->threads = thread_map__new_dummy();
1239 if (evlist->threads == NULL)
1240 goto out_free_cpus;
1241
1242 err = 0;
1243out:
1244 return err;
1245out_free_cpus:
1246 cpu_map__delete(evlist->cpus);
1247 evlist->cpus = NULL;
1248 goto out;
1249}
1250
6a4bb04c 1251int perf_evlist__open(struct perf_evlist *evlist)
727ab04e 1252{
6a4bb04c 1253 struct perf_evsel *evsel;
a74b4b66 1254 int err;
727ab04e 1255
4112eb18
ACM
1256 /*
1257 * Default: one fd per CPU, all threads, aka systemwide
1258 * as sys_perf_event_open(cpu = -1, thread = -1) is EINVAL
1259 */
1260 if (evlist->threads == NULL && evlist->cpus == NULL) {
1261 err = perf_evlist__create_syswide_maps(evlist);
1262 if (err < 0)
1263 goto out_err;
1264 }
1265
733cd2fe
AH
1266 perf_evlist__update_id_pos(evlist);
1267
0050f7aa 1268 evlist__for_each(evlist, evsel) {
6a4bb04c 1269 err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
727ab04e
ACM
1270 if (err < 0)
1271 goto out_err;
1272 }
1273
1274 return 0;
1275out_err:
a74b4b66 1276 perf_evlist__close(evlist);
41c21a68 1277 errno = -err;
727ab04e
ACM
1278 return err;
1279}
35b9d88e 1280
602ad878 1281int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
55e162ea 1282 const char *argv[], bool pipe_output,
735f7e0b 1283 void (*exec_error)(int signo, siginfo_t *info, void *ucontext))
35b9d88e
ACM
1284{
1285 int child_ready_pipe[2], go_pipe[2];
1286 char bf;
1287
1288 if (pipe(child_ready_pipe) < 0) {
1289 perror("failed to create 'ready' pipe");
1290 return -1;
1291 }
1292
1293 if (pipe(go_pipe) < 0) {
1294 perror("failed to create 'go' pipe");
1295 goto out_close_ready_pipe;
1296 }
1297
1298 evlist->workload.pid = fork();
1299 if (evlist->workload.pid < 0) {
1300 perror("failed to fork");
1301 goto out_close_pipes;
1302 }
1303
1304 if (!evlist->workload.pid) {
5f1c4225
ACM
1305 int ret;
1306
119fa3c9 1307 if (pipe_output)
35b9d88e
ACM
1308 dup2(2, 1);
1309
0817df08
DA
1310 signal(SIGTERM, SIG_DFL);
1311
35b9d88e
ACM
1312 close(child_ready_pipe[0]);
1313 close(go_pipe[1]);
1314 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
1315
35b9d88e
ACM
1316 /*
1317 * Tell the parent we're ready to go
1318 */
1319 close(child_ready_pipe[1]);
1320
1321 /*
1322 * Wait until the parent tells us to go.
1323 */
5f1c4225
ACM
1324 ret = read(go_pipe[0], &bf, 1);
1325 /*
1326 * The parent will ask for the execvp() to be performed by
1327 * writing exactly one byte, in workload.cork_fd, usually via
1328 * perf_evlist__start_workload().
1329 *
1330 * For cancelling the workload without actuallin running it,
1331 * the parent will just close workload.cork_fd, without writing
1332 * anything, i.e. read will return zero and we just exit()
1333 * here.
1334 */
1335 if (ret != 1) {
1336 if (ret == -1)
1337 perror("unable to read pipe");
1338 exit(ret);
1339 }
35b9d88e
ACM
1340
1341 execvp(argv[0], (char **)argv);
1342
735f7e0b 1343 if (exec_error) {
f33cbe72
ACM
1344 union sigval val;
1345
1346 val.sival_int = errno;
1347 if (sigqueue(getppid(), SIGUSR1, val))
1348 perror(argv[0]);
1349 } else
1350 perror(argv[0]);
35b9d88e
ACM
1351 exit(-1);
1352 }
1353
735f7e0b
ACM
1354 if (exec_error) {
1355 struct sigaction act = {
1356 .sa_flags = SA_SIGINFO,
1357 .sa_sigaction = exec_error,
1358 };
1359 sigaction(SIGUSR1, &act, NULL);
1360 }
1361
1aaf63b1
ACM
1362 if (target__none(target)) {
1363 if (evlist->threads == NULL) {
1364 fprintf(stderr, "FATAL: evlist->threads need to be set at this point (%s:%d).\n",
1365 __func__, __LINE__);
1366 goto out_close_pipes;
1367 }
35b9d88e 1368 evlist->threads->map[0] = evlist->workload.pid;
1aaf63b1 1369 }
35b9d88e
ACM
1370
1371 close(child_ready_pipe[1]);
1372 close(go_pipe[0]);
1373 /*
1374 * wait for child to settle
1375 */
1376 if (read(child_ready_pipe[0], &bf, 1) == -1) {
1377 perror("unable to read pipe");
1378 goto out_close_pipes;
1379 }
1380
bcf3145f 1381 fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
35b9d88e
ACM
1382 evlist->workload.cork_fd = go_pipe[1];
1383 close(child_ready_pipe[0]);
1384 return 0;
1385
1386out_close_pipes:
1387 close(go_pipe[0]);
1388 close(go_pipe[1]);
1389out_close_ready_pipe:
1390 close(child_ready_pipe[0]);
1391 close(child_ready_pipe[1]);
1392 return -1;
1393}
1394
1395int perf_evlist__start_workload(struct perf_evlist *evlist)
1396{
1397 if (evlist->workload.cork_fd > 0) {
b3824404 1398 char bf = 0;
bcf3145f 1399 int ret;
35b9d88e
ACM
1400 /*
1401 * Remove the cork, let it rip!
1402 */
bcf3145f
NK
1403 ret = write(evlist->workload.cork_fd, &bf, 1);
1404 if (ret < 0)
1405 perror("enable to write to pipe");
1406
1407 close(evlist->workload.cork_fd);
1408 return ret;
35b9d88e
ACM
1409 }
1410
1411 return 0;
1412}
cb0b29e0 1413
a3f698fe 1414int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event,
0807d2d8 1415 struct perf_sample *sample)
cb0b29e0 1416{
75562573
AH
1417 struct perf_evsel *evsel = perf_evlist__event2evsel(evlist, event);
1418
1419 if (!evsel)
1420 return -EFAULT;
0807d2d8 1421 return perf_evsel__parse_sample(evsel, event, sample);
cb0b29e0 1422}
78f067b3
ACM
1423
1424size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp)
1425{
1426 struct perf_evsel *evsel;
1427 size_t printed = 0;
1428
0050f7aa 1429 evlist__for_each(evlist, evsel) {
78f067b3
ACM
1430 printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "",
1431 perf_evsel__name(evsel));
1432 }
1433
b2222139 1434 return printed + fprintf(fp, "\n");
78f067b3 1435}
6ef068cb
ACM
1436
1437int perf_evlist__strerror_tp(struct perf_evlist *evlist __maybe_unused,
1438 int err, char *buf, size_t size)
1439{
1440 char sbuf[128];
1441
1442 switch (err) {
1443 case ENOENT:
1444 scnprintf(buf, size, "%s",
1445 "Error:\tUnable to find debugfs\n"
1446 "Hint:\tWas your kernel was compiled with debugfs support?\n"
1447 "Hint:\tIs the debugfs filesystem mounted?\n"
1448 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
1449 break;
1450 case EACCES:
1451 scnprintf(buf, size,
1452 "Error:\tNo permissions to read %s/tracing/events/raw_syscalls\n"
1453 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
1454 debugfs_mountpoint, debugfs_mountpoint);
1455 break;
1456 default:
1457 scnprintf(buf, size, "%s", strerror_r(err, sbuf, sizeof(sbuf)));
1458 break;
1459 }
1460
1461 return 0;
1462}
a8f23d8f
ACM
1463
1464int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
1465 int err, char *buf, size_t size)
1466{
1467 int printed, value;
6e81c74c 1468 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
a8f23d8f
ACM
1469
1470 switch (err) {
1471 case EACCES:
1472 case EPERM:
1473 printed = scnprintf(buf, size,
1474 "Error:\t%s.\n"
1475 "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg);
1476
1a47245d 1477 value = perf_event_paranoid();
a8f23d8f
ACM
1478
1479 printed += scnprintf(buf + printed, size - printed, "\nHint:\t");
1480
1481 if (value >= 2) {
1482 printed += scnprintf(buf + printed, size - printed,
1483 "For your workloads it needs to be <= 1\nHint:\t");
1484 }
1485 printed += scnprintf(buf + printed, size - printed,
5229e366 1486 "For system wide tracing it needs to be set to -1.\n");
a8f23d8f
ACM
1487
1488 printed += scnprintf(buf + printed, size - printed,
5229e366
ACM
1489 "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n"
1490 "Hint:\tThe current value is %d.", value);
a8f23d8f
ACM
1491 break;
1492 default:
1493 scnprintf(buf, size, "%s", emsg);
1494 break;
1495 }
1496
1497 return 0;
1498}
a025e4f0 1499
956fa571
ACM
1500int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
1501{
1502 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
e965bea1 1503 int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0;
956fa571
ACM
1504
1505 switch (err) {
1506 case EPERM:
e5d4a290 1507 sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user);
e965bea1
ACM
1508 printed += scnprintf(buf + printed, size - printed,
1509 "Error:\t%s.\n"
956fa571 1510 "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
e965bea1 1511 "Hint:\tTried using %zd kB.\n",
e5d4a290 1512 emsg, pages_max_per_user, pages_attempted);
e965bea1
ACM
1513
1514 if (pages_attempted >= pages_max_per_user) {
1515 printed += scnprintf(buf + printed, size - printed,
1516 "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n",
1517 pages_max_per_user + pages_attempted);
1518 }
1519
1520 printed += scnprintf(buf + printed, size - printed,
1521 "Hint:\tTry using a smaller -m/--mmap-pages value.");
956fa571
ACM
1522 break;
1523 default:
1524 scnprintf(buf, size, "%s", emsg);
1525 break;
1526 }
1527
1528 return 0;
1529}
1530
a025e4f0
AH
1531void perf_evlist__to_front(struct perf_evlist *evlist,
1532 struct perf_evsel *move_evsel)
1533{
1534 struct perf_evsel *evsel, *n;
1535 LIST_HEAD(move);
1536
1537 if (move_evsel == perf_evlist__first(evlist))
1538 return;
1539
0050f7aa 1540 evlist__for_each_safe(evlist, n, evsel) {
a025e4f0
AH
1541 if (evsel->leader == move_evsel->leader)
1542 list_move_tail(&evsel->node, &move);
1543 }
1544
1545 list_splice(&move, &evlist->entries);
1546}
60b0896c
AH
1547
1548void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
1549 struct perf_evsel *tracking_evsel)
1550{
1551 struct perf_evsel *evsel;
1552
1553 if (tracking_evsel->tracking)
1554 return;
1555
1556 evlist__for_each(evlist, evsel) {
1557 if (evsel != tracking_evsel)
1558 evsel->tracking = false;
1559 }
1560
1561 tracking_evsel->tracking = true;
1562}