2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
4 * Parts came from builtin-{top,stat,record}.c, see those files for further
7 * Released under the GPL v2. (and only v2, not any later version)
10 #include <api/fs/debugfs.h>
13 #include "thread_map.h"
20 #include "parse-events.h"
21 #include "parse-options.h"
25 #include <linux/bitops.h>
26 #include <linux/hash.h>
28 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
29 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
31 void perf_evlist__init(struct perf_evlist
*evlist
, struct cpu_map
*cpus
,
32 struct thread_map
*threads
)
36 for (i
= 0; i
< PERF_EVLIST__HLIST_SIZE
; ++i
)
37 INIT_HLIST_HEAD(&evlist
->heads
[i
]);
38 INIT_LIST_HEAD(&evlist
->entries
);
39 perf_evlist__set_maps(evlist
, cpus
, threads
);
40 fdarray__init(&evlist
->pollfd
, 64);
41 evlist
->workload
.pid
= -1;
44 struct perf_evlist
*perf_evlist__new(void)
46 struct perf_evlist
*evlist
= zalloc(sizeof(*evlist
));
49 perf_evlist__init(evlist
, NULL
, NULL
);
54 struct perf_evlist
*perf_evlist__new_default(void)
56 struct perf_evlist
*evlist
= perf_evlist__new();
58 if (evlist
&& perf_evlist__add_default(evlist
)) {
59 perf_evlist__delete(evlist
);
67 * perf_evlist__set_id_pos - set the positions of event ids.
68 * @evlist: selected event list
70 * Events with compatible sample types all have the same id_pos
71 * and is_pos. For convenience, put a copy on evlist.
73 void perf_evlist__set_id_pos(struct perf_evlist
*evlist
)
75 struct perf_evsel
*first
= perf_evlist__first(evlist
);
77 evlist
->id_pos
= first
->id_pos
;
78 evlist
->is_pos
= first
->is_pos
;
81 static void perf_evlist__update_id_pos(struct perf_evlist
*evlist
)
83 struct perf_evsel
*evsel
;
85 evlist__for_each(evlist
, evsel
)
86 perf_evsel__calc_id_pos(evsel
);
88 perf_evlist__set_id_pos(evlist
);
91 static void perf_evlist__purge(struct perf_evlist
*evlist
)
93 struct perf_evsel
*pos
, *n
;
95 evlist__for_each_safe(evlist
, n
, pos
) {
96 list_del_init(&pos
->node
);
97 perf_evsel__delete(pos
);
100 evlist
->nr_entries
= 0;
103 void perf_evlist__exit(struct perf_evlist
*evlist
)
105 zfree(&evlist
->mmap
);
106 fdarray__exit(&evlist
->pollfd
);
109 void perf_evlist__delete(struct perf_evlist
*evlist
)
111 perf_evlist__munmap(evlist
);
112 perf_evlist__close(evlist
);
113 cpu_map__delete(evlist
->cpus
);
114 thread_map__delete(evlist
->threads
);
116 evlist
->threads
= NULL
;
117 perf_evlist__purge(evlist
);
118 perf_evlist__exit(evlist
);
122 void perf_evlist__add(struct perf_evlist
*evlist
, struct perf_evsel
*entry
)
124 list_add_tail(&entry
->node
, &evlist
->entries
);
125 entry
->idx
= evlist
->nr_entries
;
126 entry
->tracking
= !entry
->idx
;
128 if (!evlist
->nr_entries
++)
129 perf_evlist__set_id_pos(evlist
);
132 void perf_evlist__splice_list_tail(struct perf_evlist
*evlist
,
133 struct list_head
*list
,
136 bool set_id_pos
= !evlist
->nr_entries
;
138 list_splice_tail(list
, &evlist
->entries
);
139 evlist
->nr_entries
+= nr_entries
;
141 perf_evlist__set_id_pos(evlist
);
144 void __perf_evlist__set_leader(struct list_head
*list
)
146 struct perf_evsel
*evsel
, *leader
;
148 leader
= list_entry(list
->next
, struct perf_evsel
, node
);
149 evsel
= list_entry(list
->prev
, struct perf_evsel
, node
);
151 leader
->nr_members
= evsel
->idx
- leader
->idx
+ 1;
153 __evlist__for_each(list
, evsel
) {
154 evsel
->leader
= leader
;
158 void perf_evlist__set_leader(struct perf_evlist
*evlist
)
160 if (evlist
->nr_entries
) {
161 evlist
->nr_groups
= evlist
->nr_entries
> 1 ? 1 : 0;
162 __perf_evlist__set_leader(&evlist
->entries
);
166 int perf_evlist__add_default(struct perf_evlist
*evlist
)
168 struct perf_event_attr attr
= {
169 .type
= PERF_TYPE_HARDWARE
,
170 .config
= PERF_COUNT_HW_CPU_CYCLES
,
172 struct perf_evsel
*evsel
;
174 event_attr_init(&attr
);
176 evsel
= perf_evsel__new(&attr
);
180 /* use strdup() because free(evsel) assumes name is allocated */
181 evsel
->name
= strdup("cycles");
185 perf_evlist__add(evlist
, evsel
);
188 perf_evsel__delete(evsel
);
193 static int perf_evlist__add_attrs(struct perf_evlist
*evlist
,
194 struct perf_event_attr
*attrs
, size_t nr_attrs
)
196 struct perf_evsel
*evsel
, *n
;
200 for (i
= 0; i
< nr_attrs
; i
++) {
201 evsel
= perf_evsel__new_idx(attrs
+ i
, evlist
->nr_entries
+ i
);
203 goto out_delete_partial_list
;
204 list_add_tail(&evsel
->node
, &head
);
207 perf_evlist__splice_list_tail(evlist
, &head
, nr_attrs
);
211 out_delete_partial_list
:
212 __evlist__for_each_safe(&head
, n
, evsel
)
213 perf_evsel__delete(evsel
);
217 int __perf_evlist__add_default_attrs(struct perf_evlist
*evlist
,
218 struct perf_event_attr
*attrs
, size_t nr_attrs
)
222 for (i
= 0; i
< nr_attrs
; i
++)
223 event_attr_init(attrs
+ i
);
225 return perf_evlist__add_attrs(evlist
, attrs
, nr_attrs
);
229 perf_evlist__find_tracepoint_by_id(struct perf_evlist
*evlist
, int id
)
231 struct perf_evsel
*evsel
;
233 evlist__for_each(evlist
, evsel
) {
234 if (evsel
->attr
.type
== PERF_TYPE_TRACEPOINT
&&
235 (int)evsel
->attr
.config
== id
)
243 perf_evlist__find_tracepoint_by_name(struct perf_evlist
*evlist
,
246 struct perf_evsel
*evsel
;
248 evlist__for_each(evlist
, evsel
) {
249 if ((evsel
->attr
.type
== PERF_TYPE_TRACEPOINT
) &&
250 (strcmp(evsel
->name
, name
) == 0))
257 int perf_evlist__add_newtp(struct perf_evlist
*evlist
,
258 const char *sys
, const char *name
, void *handler
)
260 struct perf_evsel
*evsel
= perf_evsel__newtp(sys
, name
);
265 evsel
->handler
= handler
;
266 perf_evlist__add(evlist
, evsel
);
270 static int perf_evlist__nr_threads(struct perf_evlist
*evlist
,
271 struct perf_evsel
*evsel
)
273 if (evsel
->system_wide
)
276 return thread_map__nr(evlist
->threads
);
279 void perf_evlist__disable(struct perf_evlist
*evlist
)
282 struct perf_evsel
*pos
;
283 int nr_cpus
= cpu_map__nr(evlist
->cpus
);
286 for (cpu
= 0; cpu
< nr_cpus
; cpu
++) {
287 evlist__for_each(evlist
, pos
) {
288 if (!perf_evsel__is_group_leader(pos
) || !pos
->fd
)
290 nr_threads
= perf_evlist__nr_threads(evlist
, pos
);
291 for (thread
= 0; thread
< nr_threads
; thread
++)
292 ioctl(FD(pos
, cpu
, thread
),
293 PERF_EVENT_IOC_DISABLE
, 0);
298 void perf_evlist__enable(struct perf_evlist
*evlist
)
301 struct perf_evsel
*pos
;
302 int nr_cpus
= cpu_map__nr(evlist
->cpus
);
305 for (cpu
= 0; cpu
< nr_cpus
; cpu
++) {
306 evlist__for_each(evlist
, pos
) {
307 if (!perf_evsel__is_group_leader(pos
) || !pos
->fd
)
309 nr_threads
= perf_evlist__nr_threads(evlist
, pos
);
310 for (thread
= 0; thread
< nr_threads
; thread
++)
311 ioctl(FD(pos
, cpu
, thread
),
312 PERF_EVENT_IOC_ENABLE
, 0);
317 int perf_evlist__disable_event(struct perf_evlist
*evlist
,
318 struct perf_evsel
*evsel
)
320 int cpu
, thread
, err
;
321 int nr_cpus
= cpu_map__nr(evlist
->cpus
);
322 int nr_threads
= perf_evlist__nr_threads(evlist
, evsel
);
327 for (cpu
= 0; cpu
< nr_cpus
; cpu
++) {
328 for (thread
= 0; thread
< nr_threads
; thread
++) {
329 err
= ioctl(FD(evsel
, cpu
, thread
),
330 PERF_EVENT_IOC_DISABLE
, 0);
338 int perf_evlist__enable_event(struct perf_evlist
*evlist
,
339 struct perf_evsel
*evsel
)
341 int cpu
, thread
, err
;
342 int nr_cpus
= cpu_map__nr(evlist
->cpus
);
343 int nr_threads
= perf_evlist__nr_threads(evlist
, evsel
);
348 for (cpu
= 0; cpu
< nr_cpus
; cpu
++) {
349 for (thread
= 0; thread
< nr_threads
; thread
++) {
350 err
= ioctl(FD(evsel
, cpu
, thread
),
351 PERF_EVENT_IOC_ENABLE
, 0);
359 static int perf_evlist__enable_event_cpu(struct perf_evlist
*evlist
,
360 struct perf_evsel
*evsel
, int cpu
)
363 int nr_threads
= perf_evlist__nr_threads(evlist
, evsel
);
368 for (thread
= 0; thread
< nr_threads
; thread
++) {
369 err
= ioctl(FD(evsel
, cpu
, thread
),
370 PERF_EVENT_IOC_ENABLE
, 0);
377 static int perf_evlist__enable_event_thread(struct perf_evlist
*evlist
,
378 struct perf_evsel
*evsel
,
382 int nr_cpus
= cpu_map__nr(evlist
->cpus
);
387 for (cpu
= 0; cpu
< nr_cpus
; cpu
++) {
388 err
= ioctl(FD(evsel
, cpu
, thread
), PERF_EVENT_IOC_ENABLE
, 0);
395 int perf_evlist__enable_event_idx(struct perf_evlist
*evlist
,
396 struct perf_evsel
*evsel
, int idx
)
398 bool per_cpu_mmaps
= !cpu_map__empty(evlist
->cpus
);
401 return perf_evlist__enable_event_cpu(evlist
, evsel
, idx
);
403 return perf_evlist__enable_event_thread(evlist
, evsel
, idx
);
406 int perf_evlist__alloc_pollfd(struct perf_evlist
*evlist
)
408 int nr_cpus
= cpu_map__nr(evlist
->cpus
);
409 int nr_threads
= thread_map__nr(evlist
->threads
);
411 struct perf_evsel
*evsel
;
413 list_for_each_entry(evsel
, &evlist
->entries
, node
) {
414 if (evsel
->system_wide
)
417 nfds
+= nr_cpus
* nr_threads
;
420 if (fdarray__available_entries(&evlist
->pollfd
) < nfds
&&
421 fdarray__grow(&evlist
->pollfd
, nfds
) < 0)
427 int perf_evlist__add_pollfd(struct perf_evlist
*evlist
, int fd
)
429 fcntl(fd
, F_SETFL
, O_NONBLOCK
);
431 return fdarray__add(&evlist
->pollfd
, fd
, POLLIN
| POLLERR
| POLLHUP
);
434 int perf_evlist__filter_pollfd(struct perf_evlist
*evlist
, short revents_and_mask
)
436 return fdarray__filter(&evlist
->pollfd
, revents_and_mask
);
439 int perf_evlist__poll(struct perf_evlist
*evlist
, int timeout
)
441 return fdarray__poll(&evlist
->pollfd
, timeout
);
444 static void perf_evlist__id_hash(struct perf_evlist
*evlist
,
445 struct perf_evsel
*evsel
,
446 int cpu
, int thread
, u64 id
)
449 struct perf_sample_id
*sid
= SID(evsel
, cpu
, thread
);
453 hash
= hash_64(sid
->id
, PERF_EVLIST__HLIST_BITS
);
454 hlist_add_head(&sid
->node
, &evlist
->heads
[hash
]);
457 void perf_evlist__id_add(struct perf_evlist
*evlist
, struct perf_evsel
*evsel
,
458 int cpu
, int thread
, u64 id
)
460 perf_evlist__id_hash(evlist
, evsel
, cpu
, thread
, id
);
461 evsel
->id
[evsel
->ids
++] = id
;
464 static int perf_evlist__id_add_fd(struct perf_evlist
*evlist
,
465 struct perf_evsel
*evsel
,
466 int cpu
, int thread
, int fd
)
468 u64 read_data
[4] = { 0, };
469 int id_idx
= 1; /* The first entry is the counter value */
473 ret
= ioctl(fd
, PERF_EVENT_IOC_ID
, &id
);
480 /* Legacy way to get event id.. All hail to old kernels! */
483 * This way does not work with group format read, so bail
486 if (perf_evlist__read_format(evlist
) & PERF_FORMAT_GROUP
)
489 if (!(evsel
->attr
.read_format
& PERF_FORMAT_ID
) ||
490 read(fd
, &read_data
, sizeof(read_data
)) == -1)
493 if (evsel
->attr
.read_format
& PERF_FORMAT_TOTAL_TIME_ENABLED
)
495 if (evsel
->attr
.read_format
& PERF_FORMAT_TOTAL_TIME_RUNNING
)
498 id
= read_data
[id_idx
];
501 perf_evlist__id_add(evlist
, evsel
, cpu
, thread
, id
);
505 struct perf_sample_id
*perf_evlist__id2sid(struct perf_evlist
*evlist
, u64 id
)
507 struct hlist_head
*head
;
508 struct perf_sample_id
*sid
;
511 hash
= hash_64(id
, PERF_EVLIST__HLIST_BITS
);
512 head
= &evlist
->heads
[hash
];
514 hlist_for_each_entry(sid
, head
, node
)
521 struct perf_evsel
*perf_evlist__id2evsel(struct perf_evlist
*evlist
, u64 id
)
523 struct perf_sample_id
*sid
;
525 if (evlist
->nr_entries
== 1)
526 return perf_evlist__first(evlist
);
528 sid
= perf_evlist__id2sid(evlist
, id
);
532 if (!perf_evlist__sample_id_all(evlist
))
533 return perf_evlist__first(evlist
);
538 static int perf_evlist__event2id(struct perf_evlist
*evlist
,
539 union perf_event
*event
, u64
*id
)
541 const u64
*array
= event
->sample
.array
;
544 n
= (event
->header
.size
- sizeof(event
->header
)) >> 3;
546 if (event
->header
.type
== PERF_RECORD_SAMPLE
) {
547 if (evlist
->id_pos
>= n
)
549 *id
= array
[evlist
->id_pos
];
551 if (evlist
->is_pos
> n
)
559 static struct perf_evsel
*perf_evlist__event2evsel(struct perf_evlist
*evlist
,
560 union perf_event
*event
)
562 struct perf_evsel
*first
= perf_evlist__first(evlist
);
563 struct hlist_head
*head
;
564 struct perf_sample_id
*sid
;
568 if (evlist
->nr_entries
== 1)
571 if (!first
->attr
.sample_id_all
&&
572 event
->header
.type
!= PERF_RECORD_SAMPLE
)
575 if (perf_evlist__event2id(evlist
, event
, &id
))
578 /* Synthesized events have an id of zero */
582 hash
= hash_64(id
, PERF_EVLIST__HLIST_BITS
);
583 head
= &evlist
->heads
[hash
];
585 hlist_for_each_entry(sid
, head
, node
) {
592 union perf_event
*perf_evlist__mmap_read(struct perf_evlist
*evlist
, int idx
)
594 struct perf_mmap
*md
= &evlist
->mmap
[idx
];
595 unsigned int head
= perf_mmap__read_head(md
);
596 unsigned int old
= md
->prev
;
597 unsigned char *data
= md
->base
+ page_size
;
598 union perf_event
*event
= NULL
;
600 if (evlist
->overwrite
) {
602 * If we're further behind than half the buffer, there's a chance
603 * the writer will bite our tail and mess up the samples under us.
605 * If we somehow ended up ahead of the head, we got messed up.
607 * In either case, truncate and restart at head.
609 int diff
= head
- old
;
610 if (diff
> md
->mask
/ 2 || diff
< 0) {
611 fprintf(stderr
, "WARNING: failed to keep up with mmap data.\n");
614 * head points to a known good entry, start there.
623 event
= (union perf_event
*)&data
[old
& md
->mask
];
624 size
= event
->header
.size
;
627 * Event straddles the mmap boundary -- header should always
628 * be inside due to u64 alignment of output.
630 if ((old
& md
->mask
) + size
!= ((old
+ size
) & md
->mask
)) {
631 unsigned int offset
= old
;
632 unsigned int len
= min(sizeof(*event
), size
), cpy
;
633 void *dst
= md
->event_copy
;
636 cpy
= min(md
->mask
+ 1 - (offset
& md
->mask
), len
);
637 memcpy(dst
, &data
[offset
& md
->mask
], cpy
);
643 event
= (union perf_event
*) md
->event_copy
;
654 void perf_evlist__mmap_consume(struct perf_evlist
*evlist
, int idx
)
656 if (!evlist
->overwrite
) {
657 struct perf_mmap
*md
= &evlist
->mmap
[idx
];
658 unsigned int old
= md
->prev
;
660 perf_mmap__write_tail(md
, old
);
664 static void __perf_evlist__munmap(struct perf_evlist
*evlist
, int idx
)
666 if (evlist
->mmap
[idx
].base
!= NULL
) {
667 munmap(evlist
->mmap
[idx
].base
, evlist
->mmap_len
);
668 evlist
->mmap
[idx
].base
= NULL
;
672 void perf_evlist__munmap(struct perf_evlist
*evlist
)
676 if (evlist
->mmap
== NULL
)
679 for (i
= 0; i
< evlist
->nr_mmaps
; i
++)
680 __perf_evlist__munmap(evlist
, i
);
682 zfree(&evlist
->mmap
);
685 static int perf_evlist__alloc_mmap(struct perf_evlist
*evlist
)
687 evlist
->nr_mmaps
= cpu_map__nr(evlist
->cpus
);
688 if (cpu_map__empty(evlist
->cpus
))
689 evlist
->nr_mmaps
= thread_map__nr(evlist
->threads
);
690 evlist
->mmap
= zalloc(evlist
->nr_mmaps
* sizeof(struct perf_mmap
));
691 return evlist
->mmap
!= NULL
? 0 : -ENOMEM
;
699 static int __perf_evlist__mmap(struct perf_evlist
*evlist
, int idx
,
700 struct mmap_params
*mp
, int fd
)
702 evlist
->mmap
[idx
].prev
= 0;
703 evlist
->mmap
[idx
].mask
= mp
->mask
;
704 evlist
->mmap
[idx
].base
= mmap(NULL
, evlist
->mmap_len
, mp
->prot
,
706 if (evlist
->mmap
[idx
].base
== MAP_FAILED
) {
707 pr_debug2("failed to mmap perf event ring buffer, error %d\n",
709 evlist
->mmap
[idx
].base
= NULL
;
716 static int perf_evlist__mmap_per_evsel(struct perf_evlist
*evlist
, int idx
,
717 struct mmap_params
*mp
, int cpu
,
718 int thread
, int *output
)
720 struct perf_evsel
*evsel
;
722 evlist__for_each(evlist
, evsel
) {
725 if (evsel
->system_wide
&& thread
)
728 fd
= FD(evsel
, cpu
, thread
);
732 if (__perf_evlist__mmap(evlist
, idx
, mp
, *output
) < 0)
735 if (ioctl(fd
, PERF_EVENT_IOC_SET_OUTPUT
, *output
) != 0)
739 if (perf_evlist__add_pollfd(evlist
, fd
) < 0)
742 if ((evsel
->attr
.read_format
& PERF_FORMAT_ID
) &&
743 perf_evlist__id_add_fd(evlist
, evsel
, cpu
, thread
, fd
) < 0)
750 static int perf_evlist__mmap_per_cpu(struct perf_evlist
*evlist
,
751 struct mmap_params
*mp
)
754 int nr_cpus
= cpu_map__nr(evlist
->cpus
);
755 int nr_threads
= thread_map__nr(evlist
->threads
);
757 pr_debug2("perf event ring buffer mmapped per cpu\n");
758 for (cpu
= 0; cpu
< nr_cpus
; cpu
++) {
761 for (thread
= 0; thread
< nr_threads
; thread
++) {
762 if (perf_evlist__mmap_per_evsel(evlist
, cpu
, mp
, cpu
,
771 for (cpu
= 0; cpu
< nr_cpus
; cpu
++)
772 __perf_evlist__munmap(evlist
, cpu
);
776 static int perf_evlist__mmap_per_thread(struct perf_evlist
*evlist
,
777 struct mmap_params
*mp
)
780 int nr_threads
= thread_map__nr(evlist
->threads
);
782 pr_debug2("perf event ring buffer mmapped per thread\n");
783 for (thread
= 0; thread
< nr_threads
; thread
++) {
786 if (perf_evlist__mmap_per_evsel(evlist
, thread
, mp
, 0, thread
,
794 for (thread
= 0; thread
< nr_threads
; thread
++)
795 __perf_evlist__munmap(evlist
, thread
);
799 static size_t perf_evlist__mmap_size(unsigned long pages
)
801 /* 512 kiB: default amount of unprivileged mlocked memory */
802 if (pages
== UINT_MAX
)
803 pages
= (512 * 1024) / page_size
;
804 else if (!is_power_of_2(pages
))
807 return (pages
+ 1) * page_size
;
810 static long parse_pages_arg(const char *str
, unsigned long min
,
813 unsigned long pages
, val
;
814 static struct parse_tag tags
[] = {
815 { .tag
= 'B', .mult
= 1 },
816 { .tag
= 'K', .mult
= 1 << 10 },
817 { .tag
= 'M', .mult
= 1 << 20 },
818 { .tag
= 'G', .mult
= 1 << 30 },
825 val
= parse_tag_value(str
, tags
);
826 if (val
!= (unsigned long) -1) {
827 /* we got file size value */
828 pages
= PERF_ALIGN(val
, page_size
) / page_size
;
830 /* we got pages count value */
832 pages
= strtoul(str
, &eptr
, 10);
837 if (pages
== 0 && min
== 0) {
838 /* leave number of pages at 0 */
839 } else if (!is_power_of_2(pages
)) {
840 /* round pages up to next power of 2 */
841 pages
= next_pow2_l(pages
);
844 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
845 pages
* page_size
, pages
);
854 int perf_evlist__parse_mmap_pages(const struct option
*opt
, const char *str
,
855 int unset __maybe_unused
)
857 unsigned int *mmap_pages
= opt
->value
;
858 unsigned long max
= UINT_MAX
;
861 if (max
> SIZE_MAX
/ page_size
)
862 max
= SIZE_MAX
/ page_size
;
864 pages
= parse_pages_arg(str
, 1, max
);
866 pr_err("Invalid argument for --mmap_pages/-m\n");
875 * perf_evlist__mmap - Create mmaps to receive events.
876 * @evlist: list of events
877 * @pages: map length in pages
878 * @overwrite: overwrite older events?
880 * If @overwrite is %false the user needs to signal event consumption using
881 * perf_mmap__write_tail(). Using perf_evlist__mmap_read() does this
884 * Return: %0 on success, negative error code otherwise.
886 int perf_evlist__mmap(struct perf_evlist
*evlist
, unsigned int pages
,
889 struct perf_evsel
*evsel
;
890 const struct cpu_map
*cpus
= evlist
->cpus
;
891 const struct thread_map
*threads
= evlist
->threads
;
892 struct mmap_params mp
= {
893 .prot
= PROT_READ
| (overwrite
? 0 : PROT_WRITE
),
896 if (evlist
->mmap
== NULL
&& perf_evlist__alloc_mmap(evlist
) < 0)
899 if (evlist
->pollfd
.entries
== NULL
&& perf_evlist__alloc_pollfd(evlist
) < 0)
902 evlist
->overwrite
= overwrite
;
903 evlist
->mmap_len
= perf_evlist__mmap_size(pages
);
904 pr_debug("mmap size %zuB\n", evlist
->mmap_len
);
905 mp
.mask
= evlist
->mmap_len
- page_size
- 1;
907 evlist__for_each(evlist
, evsel
) {
908 if ((evsel
->attr
.read_format
& PERF_FORMAT_ID
) &&
909 evsel
->sample_id
== NULL
&&
910 perf_evsel__alloc_id(evsel
, cpu_map__nr(cpus
), threads
->nr
) < 0)
914 if (cpu_map__empty(cpus
))
915 return perf_evlist__mmap_per_thread(evlist
, &mp
);
917 return perf_evlist__mmap_per_cpu(evlist
, &mp
);
920 int perf_evlist__create_maps(struct perf_evlist
*evlist
, struct target
*target
)
922 evlist
->threads
= thread_map__new_str(target
->pid
, target
->tid
,
925 if (evlist
->threads
== NULL
)
928 if (target__uses_dummy_map(target
))
929 evlist
->cpus
= cpu_map__dummy_new();
931 evlist
->cpus
= cpu_map__new(target
->cpu_list
);
933 if (evlist
->cpus
== NULL
)
934 goto out_delete_threads
;
939 thread_map__delete(evlist
->threads
);
943 int perf_evlist__apply_filters(struct perf_evlist
*evlist
)
945 struct perf_evsel
*evsel
;
947 const int ncpus
= cpu_map__nr(evlist
->cpus
),
948 nthreads
= thread_map__nr(evlist
->threads
);
950 evlist__for_each(evlist
, evsel
) {
951 if (evsel
->filter
== NULL
)
954 err
= perf_evsel__set_filter(evsel
, ncpus
, nthreads
, evsel
->filter
);
962 int perf_evlist__set_filter(struct perf_evlist
*evlist
, const char *filter
)
964 struct perf_evsel
*evsel
;
966 const int ncpus
= cpu_map__nr(evlist
->cpus
),
967 nthreads
= thread_map__nr(evlist
->threads
);
969 evlist__for_each(evlist
, evsel
) {
970 err
= perf_evsel__set_filter(evsel
, ncpus
, nthreads
, filter
);
978 bool perf_evlist__valid_sample_type(struct perf_evlist
*evlist
)
980 struct perf_evsel
*pos
;
982 if (evlist
->nr_entries
== 1)
985 if (evlist
->id_pos
< 0 || evlist
->is_pos
< 0)
988 evlist__for_each(evlist
, pos
) {
989 if (pos
->id_pos
!= evlist
->id_pos
||
990 pos
->is_pos
!= evlist
->is_pos
)
997 u64
__perf_evlist__combined_sample_type(struct perf_evlist
*evlist
)
999 struct perf_evsel
*evsel
;
1001 if (evlist
->combined_sample_type
)
1002 return evlist
->combined_sample_type
;
1004 evlist__for_each(evlist
, evsel
)
1005 evlist
->combined_sample_type
|= evsel
->attr
.sample_type
;
1007 return evlist
->combined_sample_type
;
1010 u64
perf_evlist__combined_sample_type(struct perf_evlist
*evlist
)
1012 evlist
->combined_sample_type
= 0;
1013 return __perf_evlist__combined_sample_type(evlist
);
1016 bool perf_evlist__valid_read_format(struct perf_evlist
*evlist
)
1018 struct perf_evsel
*first
= perf_evlist__first(evlist
), *pos
= first
;
1019 u64 read_format
= first
->attr
.read_format
;
1020 u64 sample_type
= first
->attr
.sample_type
;
1022 evlist__for_each(evlist
, pos
) {
1023 if (read_format
!= pos
->attr
.read_format
)
1027 /* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */
1028 if ((sample_type
& PERF_SAMPLE_READ
) &&
1029 !(read_format
& PERF_FORMAT_ID
)) {
1036 u64
perf_evlist__read_format(struct perf_evlist
*evlist
)
1038 struct perf_evsel
*first
= perf_evlist__first(evlist
);
1039 return first
->attr
.read_format
;
1042 u16
perf_evlist__id_hdr_size(struct perf_evlist
*evlist
)
1044 struct perf_evsel
*first
= perf_evlist__first(evlist
);
1045 struct perf_sample
*data
;
1049 if (!first
->attr
.sample_id_all
)
1052 sample_type
= first
->attr
.sample_type
;
1054 if (sample_type
& PERF_SAMPLE_TID
)
1055 size
+= sizeof(data
->tid
) * 2;
1057 if (sample_type
& PERF_SAMPLE_TIME
)
1058 size
+= sizeof(data
->time
);
1060 if (sample_type
& PERF_SAMPLE_ID
)
1061 size
+= sizeof(data
->id
);
1063 if (sample_type
& PERF_SAMPLE_STREAM_ID
)
1064 size
+= sizeof(data
->stream_id
);
1066 if (sample_type
& PERF_SAMPLE_CPU
)
1067 size
+= sizeof(data
->cpu
) * 2;
1069 if (sample_type
& PERF_SAMPLE_IDENTIFIER
)
1070 size
+= sizeof(data
->id
);
1075 bool perf_evlist__valid_sample_id_all(struct perf_evlist
*evlist
)
1077 struct perf_evsel
*first
= perf_evlist__first(evlist
), *pos
= first
;
1079 evlist__for_each_continue(evlist
, pos
) {
1080 if (first
->attr
.sample_id_all
!= pos
->attr
.sample_id_all
)
1087 bool perf_evlist__sample_id_all(struct perf_evlist
*evlist
)
1089 struct perf_evsel
*first
= perf_evlist__first(evlist
);
1090 return first
->attr
.sample_id_all
;
1093 void perf_evlist__set_selected(struct perf_evlist
*evlist
,
1094 struct perf_evsel
*evsel
)
1096 evlist
->selected
= evsel
;
1099 void perf_evlist__close(struct perf_evlist
*evlist
)
1101 struct perf_evsel
*evsel
;
1102 int ncpus
= cpu_map__nr(evlist
->cpus
);
1103 int nthreads
= thread_map__nr(evlist
->threads
);
1106 evlist__for_each_reverse(evlist
, evsel
) {
1107 n
= evsel
->cpus
? evsel
->cpus
->nr
: ncpus
;
1108 perf_evsel__close(evsel
, n
, nthreads
);
1112 int perf_evlist__open(struct perf_evlist
*evlist
)
1114 struct perf_evsel
*evsel
;
1117 perf_evlist__update_id_pos(evlist
);
1119 evlist__for_each(evlist
, evsel
) {
1120 err
= perf_evsel__open(evsel
, evlist
->cpus
, evlist
->threads
);
1127 perf_evlist__close(evlist
);
1132 int perf_evlist__prepare_workload(struct perf_evlist
*evlist
, struct target
*target
,
1133 const char *argv
[], bool pipe_output
,
1134 void (*exec_error
)(int signo
, siginfo_t
*info
, void *ucontext
))
1136 int child_ready_pipe
[2], go_pipe
[2];
1139 if (pipe(child_ready_pipe
) < 0) {
1140 perror("failed to create 'ready' pipe");
1144 if (pipe(go_pipe
) < 0) {
1145 perror("failed to create 'go' pipe");
1146 goto out_close_ready_pipe
;
1149 evlist
->workload
.pid
= fork();
1150 if (evlist
->workload
.pid
< 0) {
1151 perror("failed to fork");
1152 goto out_close_pipes
;
1155 if (!evlist
->workload
.pid
) {
1161 signal(SIGTERM
, SIG_DFL
);
1163 close(child_ready_pipe
[0]);
1165 fcntl(go_pipe
[0], F_SETFD
, FD_CLOEXEC
);
1168 * Tell the parent we're ready to go
1170 close(child_ready_pipe
[1]);
1173 * Wait until the parent tells us to go.
1175 ret
= read(go_pipe
[0], &bf
, 1);
1177 * The parent will ask for the execvp() to be performed by
1178 * writing exactly one byte, in workload.cork_fd, usually via
1179 * perf_evlist__start_workload().
1181 * For cancelling the workload without actuallin running it,
1182 * the parent will just close workload.cork_fd, without writing
1183 * anything, i.e. read will return zero and we just exit()
1188 perror("unable to read pipe");
1192 execvp(argv
[0], (char **)argv
);
1197 val
.sival_int
= errno
;
1198 if (sigqueue(getppid(), SIGUSR1
, val
))
1206 struct sigaction act
= {
1207 .sa_flags
= SA_SIGINFO
,
1208 .sa_sigaction
= exec_error
,
1210 sigaction(SIGUSR1
, &act
, NULL
);
1213 if (target__none(target
))
1214 evlist
->threads
->map
[0] = evlist
->workload
.pid
;
1216 close(child_ready_pipe
[1]);
1219 * wait for child to settle
1221 if (read(child_ready_pipe
[0], &bf
, 1) == -1) {
1222 perror("unable to read pipe");
1223 goto out_close_pipes
;
1226 fcntl(go_pipe
[1], F_SETFD
, FD_CLOEXEC
);
1227 evlist
->workload
.cork_fd
= go_pipe
[1];
1228 close(child_ready_pipe
[0]);
1234 out_close_ready_pipe
:
1235 close(child_ready_pipe
[0]);
1236 close(child_ready_pipe
[1]);
1240 int perf_evlist__start_workload(struct perf_evlist
*evlist
)
1242 if (evlist
->workload
.cork_fd
> 0) {
1246 * Remove the cork, let it rip!
1248 ret
= write(evlist
->workload
.cork_fd
, &bf
, 1);
1250 perror("enable to write to pipe");
1252 close(evlist
->workload
.cork_fd
);
1259 int perf_evlist__parse_sample(struct perf_evlist
*evlist
, union perf_event
*event
,
1260 struct perf_sample
*sample
)
1262 struct perf_evsel
*evsel
= perf_evlist__event2evsel(evlist
, event
);
1266 return perf_evsel__parse_sample(evsel
, event
, sample
);
1269 size_t perf_evlist__fprintf(struct perf_evlist
*evlist
, FILE *fp
)
1271 struct perf_evsel
*evsel
;
1274 evlist__for_each(evlist
, evsel
) {
1275 printed
+= fprintf(fp
, "%s%s", evsel
->idx
? ", " : "",
1276 perf_evsel__name(evsel
));
1279 return printed
+ fprintf(fp
, "\n");
1282 int perf_evlist__strerror_tp(struct perf_evlist
*evlist __maybe_unused
,
1283 int err
, char *buf
, size_t size
)
1289 scnprintf(buf
, size
, "%s",
1290 "Error:\tUnable to find debugfs\n"
1291 "Hint:\tWas your kernel was compiled with debugfs support?\n"
1292 "Hint:\tIs the debugfs filesystem mounted?\n"
1293 "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'");
1296 scnprintf(buf
, size
,
1297 "Error:\tNo permissions to read %s/tracing/events/raw_syscalls\n"
1298 "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n",
1299 debugfs_mountpoint
, debugfs_mountpoint
);
1302 scnprintf(buf
, size
, "%s", strerror_r(err
, sbuf
, sizeof(sbuf
)));
1309 int perf_evlist__strerror_open(struct perf_evlist
*evlist __maybe_unused
,
1310 int err
, char *buf
, size_t size
)
1313 char sbuf
[STRERR_BUFSIZE
], *emsg
= strerror_r(err
, sbuf
, sizeof(sbuf
));
1318 printed
= scnprintf(buf
, size
,
1320 "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg
);
1322 value
= perf_event_paranoid();
1324 printed
+= scnprintf(buf
+ printed
, size
- printed
, "\nHint:\t");
1327 printed
+= scnprintf(buf
+ printed
, size
- printed
,
1328 "For your workloads it needs to be <= 1\nHint:\t");
1330 printed
+= scnprintf(buf
+ printed
, size
- printed
,
1331 "For system wide tracing it needs to be set to -1.\n");
1333 printed
+= scnprintf(buf
+ printed
, size
- printed
,
1334 "Hint:\tTry: 'sudo sh -c \"echo -1 > /proc/sys/kernel/perf_event_paranoid\"'\n"
1335 "Hint:\tThe current value is %d.", value
);
1338 scnprintf(buf
, size
, "%s", emsg
);
1345 void perf_evlist__to_front(struct perf_evlist
*evlist
,
1346 struct perf_evsel
*move_evsel
)
1348 struct perf_evsel
*evsel
, *n
;
1351 if (move_evsel
== perf_evlist__first(evlist
))
1354 evlist__for_each_safe(evlist
, n
, evsel
) {
1355 if (evsel
->leader
== move_evsel
->leader
)
1356 list_move_tail(&evsel
->node
, &move
);
1359 list_splice(&move
, &evlist
->entries
);
1362 void perf_evlist__set_tracking_event(struct perf_evlist
*evlist
,
1363 struct perf_evsel
*tracking_evsel
)
1365 struct perf_evsel
*evsel
;
1367 if (tracking_evsel
->tracking
)
1370 evlist__for_each(evlist
, evsel
) {
1371 if (evsel
!= tracking_evsel
)
1372 evsel
->tracking
= false;
1375 tracking_evsel
->tracking
= true;