1#include <errno.h>
2#include <inttypes.h>
3#include <linux/kernel.h>
4#include <traceevent/event-parse.h>
5#include <api/fs/fs.h>
6
7#include <byteswap.h>
8#include <unistd.h>
9#include <sys/types.h>
10#include <sys/mman.h>
11
12#include "evlist.h"
13#include "evsel.h"
14#include "memswap.h"
15#include "session.h"
16#include "tool.h"
17#include "sort.h"
18#include "util.h"
19#include "cpumap.h"
20#include "perf_regs.h"
21#include "asm/bug.h"
22#include "auxtrace.h"
23#include "thread.h"
24#include "thread-stack.h"
25#include "stat.h"
26
27static int perf_session__deliver_event(struct perf_session *session,
28 union perf_event *event,
29 struct perf_tool *tool,
30 u64 file_offset);
31
32static int perf_session__open(struct perf_session *session)
33{
34 struct perf_data *data = session->data;
35
36 if (perf_session__read_header(session) < 0) {
37 pr_err("incompatible file format (rerun with -v to learn more)\n");
38 return -1;
39 }
40
41 if (perf_data__is_pipe(data))
42 return 0;
43
44 if (perf_header__has_feat(&session->header, HEADER_STAT))
45 return 0;
46
47 if (!perf_evlist__valid_sample_type(session->evlist)) {
48 pr_err("non matching sample_type\n");
49 return -1;
50 }
51
52 if (!perf_evlist__valid_sample_id_all(session->evlist)) {
53 pr_err("non matching sample_id_all\n");
54 return -1;
55 }
56
57 if (!perf_evlist__valid_read_format(session->evlist)) {
58 pr_err("non matching read_format\n");
59 return -1;
60 }
61
62 return 0;
63}
64
65void perf_session__set_id_hdr_size(struct perf_session *session)
66{
67 u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist);
68
69 machines__set_id_hdr_size(&session->machines, id_hdr_size);
70}
71
72int perf_session__create_kernel_maps(struct perf_session *session)
73{
74 int ret = machine__create_kernel_maps(&session->machines.host);
75
76 if (ret >= 0)
77 ret = machines__create_guest_kernel_maps(&session->machines);
78 return ret;
79}
80
81static void perf_session__destroy_kernel_maps(struct perf_session *session)
82{
83 machines__destroy_kernel_maps(&session->machines);
84}
85
86static bool perf_session__has_comm_exec(struct perf_session *session)
87{
88 struct perf_evsel *evsel;
89
90 evlist__for_each_entry(session->evlist, evsel) {
91 if (evsel->attr.comm_exec)
92 return true;
93 }
94
95 return false;
96}
97
98static void perf_session__set_comm_exec(struct perf_session *session)
99{
100 bool comm_exec = perf_session__has_comm_exec(session);
101
102 machines__set_comm_exec(&session->machines, comm_exec);
103}
104
105static int ordered_events__deliver_event(struct ordered_events *oe,
106 struct ordered_event *event)
107{
108 struct perf_session *session = container_of(oe, struct perf_session,
109 ordered_events);
110
111 return perf_session__deliver_event(session, event->event,
112 session->tool, event->file_offset);
113}
114
115struct perf_session *perf_session__new(struct perf_data *data,
116 bool repipe, struct perf_tool *tool)
117{
118 struct perf_session *session = zalloc(sizeof(*session));
119
120 if (!session)
121 goto out;
122
123 session->repipe = repipe;
124 session->tool = tool;
125 INIT_LIST_HEAD(&session->auxtrace_index);
126 machines__init(&session->machines);
127 ordered_events__init(&session->ordered_events, ordered_events__deliver_event);
128
129 if (data) {
130 if (perf_data__open(data))
131 goto out_delete;
132
133 session->data = data;
134
135 if (perf_data__is_read(data)) {
136 if (perf_session__open(session) < 0)
137 goto out_close;
138
139
140
141
142
143 if (!data->is_pipe) {
144 perf_session__set_id_hdr_size(session);
145 perf_session__set_comm_exec(session);
146 }
147 }
148 } else {
149 session->machines.host.env = &perf_env;
150 }
151
152 if (!data || perf_data__is_write(data)) {
153
154
155
156
157 if (perf_session__create_kernel_maps(session) < 0)
158 pr_warning("Cannot read kernel map\n");
159 }
160
161
162
163
164
165 if ((!data || !data->is_pipe) && tool && tool->ordering_requires_timestamps &&
166 tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) {
167 dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
168 tool->ordered_events = false;
169 }
170
171 return session;
172
173 out_close:
174 perf_data__close(data);
175 out_delete:
176 perf_session__delete(session);
177 out:
178 return NULL;
179}
180
181static void perf_session__delete_threads(struct perf_session *session)
182{
183 machine__delete_threads(&session->machines.host);
184}
185
186void perf_session__delete(struct perf_session *session)
187{
188 if (session == NULL)
189 return;
190 auxtrace__free(session);
191 auxtrace_index__free(&session->auxtrace_index);
192 perf_session__destroy_kernel_maps(session);
193 perf_session__delete_threads(session);
194 perf_env__exit(&session->header.env);
195 machines__exit(&session->machines);
196 if (session->data)
197 perf_data__close(session->data);
198 free(session);
199}
200
201static int process_event_synth_tracing_data_stub(struct perf_tool *tool
202 __maybe_unused,
203 union perf_event *event
204 __maybe_unused,
205 struct perf_session *session
206 __maybe_unused)
207{
208 dump_printf(": unhandled!\n");
209 return 0;
210}
211
212static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused,
213 union perf_event *event __maybe_unused,
214 struct perf_evlist **pevlist
215 __maybe_unused)
216{
217 dump_printf(": unhandled!\n");
218 return 0;
219}
220
221static int process_event_synth_event_update_stub(struct perf_tool *tool __maybe_unused,
222 union perf_event *event __maybe_unused,
223 struct perf_evlist **pevlist
224 __maybe_unused)
225{
226 if (dump_trace)
227 perf_event__fprintf_event_update(event, stdout);
228
229 dump_printf(": unhandled!\n");
230 return 0;
231}
232
233static int process_event_sample_stub(struct perf_tool *tool __maybe_unused,
234 union perf_event *event __maybe_unused,
235 struct perf_sample *sample __maybe_unused,
236 struct perf_evsel *evsel __maybe_unused,
237 struct machine *machine __maybe_unused)
238{
239 dump_printf(": unhandled!\n");
240 return 0;
241}
242
243static int process_event_stub(struct perf_tool *tool __maybe_unused,
244 union perf_event *event __maybe_unused,
245 struct perf_sample *sample __maybe_unused,
246 struct machine *machine __maybe_unused)
247{
248 dump_printf(": unhandled!\n");
249 return 0;
250}
251
252static int process_finished_round_stub(struct perf_tool *tool __maybe_unused,
253 union perf_event *event __maybe_unused,
254 struct ordered_events *oe __maybe_unused)
255{
256 dump_printf(": unhandled!\n");
257 return 0;
258}
259
260static int process_finished_round(struct perf_tool *tool,
261 union perf_event *event,
262 struct ordered_events *oe);
263
264static int skipn(int fd, off_t n)
265{
266 char buf[4096];
267 ssize_t ret;
268
269 while (n > 0) {
270 ret = read(fd, buf, min(n, (off_t)sizeof(buf)));
271 if (ret <= 0)
272 return ret;
273 n -= ret;
274 }
275
276 return 0;
277}
278
279static s64 process_event_auxtrace_stub(struct perf_tool *tool __maybe_unused,
280 union perf_event *event,
281 struct perf_session *session
282 __maybe_unused)
283{
284 dump_printf(": unhandled!\n");
285 if (perf_data__is_pipe(session->data))
286 skipn(perf_data__fd(session->data), event->auxtrace.size);
287 return event->auxtrace.size;
288}
289
290static int process_event_op2_stub(struct perf_tool *tool __maybe_unused,
291 union perf_event *event __maybe_unused,
292 struct perf_session *session __maybe_unused)
293{
294 dump_printf(": unhandled!\n");
295 return 0;
296}
297
298
299static
300int process_event_thread_map_stub(struct perf_tool *tool __maybe_unused,
301 union perf_event *event __maybe_unused,
302 struct perf_session *session __maybe_unused)
303{
304 if (dump_trace)
305 perf_event__fprintf_thread_map(event, stdout);
306
307 dump_printf(": unhandled!\n");
308 return 0;
309}
310
311static
312int process_event_cpu_map_stub(struct perf_tool *tool __maybe_unused,
313 union perf_event *event __maybe_unused,
314 struct perf_session *session __maybe_unused)
315{
316 if (dump_trace)
317 perf_event__fprintf_cpu_map(event, stdout);
318
319 dump_printf(": unhandled!\n");
320 return 0;
321}
322
323static
324int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,
325 union perf_event *event __maybe_unused,
326 struct perf_session *session __maybe_unused)
327{
328 if (dump_trace)
329 perf_event__fprintf_stat_config(event, stdout);
330
331 dump_printf(": unhandled!\n");
332 return 0;
333}
334
335static int process_stat_stub(struct perf_tool *tool __maybe_unused,
336 union perf_event *event __maybe_unused,
337 struct perf_session *perf_session
338 __maybe_unused)
339{
340 if (dump_trace)
341 perf_event__fprintf_stat(event, stdout);
342
343 dump_printf(": unhandled!\n");
344 return 0;
345}
346
347static int process_stat_round_stub(struct perf_tool *tool __maybe_unused,
348 union perf_event *event __maybe_unused,
349 struct perf_session *perf_session
350 __maybe_unused)
351{
352 if (dump_trace)
353 perf_event__fprintf_stat_round(event, stdout);
354
355 dump_printf(": unhandled!\n");
356 return 0;
357}
358
359void perf_tool__fill_defaults(struct perf_tool *tool)
360{
361 if (tool->sample == NULL)
362 tool->sample = process_event_sample_stub;
363 if (tool->mmap == NULL)
364 tool->mmap = process_event_stub;
365 if (tool->mmap2 == NULL)
366 tool->mmap2 = process_event_stub;
367 if (tool->comm == NULL)
368 tool->comm = process_event_stub;
369 if (tool->fork == NULL)
370 tool->fork = process_event_stub;
371 if (tool->exit == NULL)
372 tool->exit = process_event_stub;
373 if (tool->lost == NULL)
374 tool->lost = perf_event__process_lost;
375 if (tool->lost_samples == NULL)
376 tool->lost_samples = perf_event__process_lost_samples;
377 if (tool->aux == NULL)
378 tool->aux = perf_event__process_aux;
379 if (tool->itrace_start == NULL)
380 tool->itrace_start = perf_event__process_itrace_start;
381 if (tool->context_switch == NULL)
382 tool->context_switch = perf_event__process_switch;
383 if (tool->read == NULL)
384 tool->read = process_event_sample_stub;
385 if (tool->throttle == NULL)
386 tool->throttle = process_event_stub;
387 if (tool->unthrottle == NULL)
388 tool->unthrottle = process_event_stub;
389 if (tool->attr == NULL)
390 tool->attr = process_event_synth_attr_stub;
391 if (tool->event_update == NULL)
392 tool->event_update = process_event_synth_event_update_stub;
393 if (tool->tracing_data == NULL)
394 tool->tracing_data = process_event_synth_tracing_data_stub;
395 if (tool->build_id == NULL)
396 tool->build_id = process_event_op2_stub;
397 if (tool->finished_round == NULL) {
398 if (tool->ordered_events)
399 tool->finished_round = process_finished_round;
400 else
401 tool->finished_round = process_finished_round_stub;
402 }
403 if (tool->id_index == NULL)
404 tool->id_index = process_event_op2_stub;
405 if (tool->auxtrace_info == NULL)
406 tool->auxtrace_info = process_event_op2_stub;
407 if (tool->auxtrace == NULL)
408 tool->auxtrace = process_event_auxtrace_stub;
409 if (tool->auxtrace_error == NULL)
410 tool->auxtrace_error = process_event_op2_stub;
411 if (tool->thread_map == NULL)
412 tool->thread_map = process_event_thread_map_stub;
413 if (tool->cpu_map == NULL)
414 tool->cpu_map = process_event_cpu_map_stub;
415 if (tool->stat_config == NULL)
416 tool->stat_config = process_event_stat_config_stub;
417 if (tool->stat == NULL)
418 tool->stat = process_stat_stub;
419 if (tool->stat_round == NULL)
420 tool->stat_round = process_stat_round_stub;
421 if (tool->time_conv == NULL)
422 tool->time_conv = process_event_op2_stub;
423 if (tool->feature == NULL)
424 tool->feature = process_event_op2_stub;
425}
426
427static void swap_sample_id_all(union perf_event *event, void *data)
428{
429 void *end = (void *) event + event->header.size;
430 int size = end - data;
431
432 BUG_ON(size % sizeof(u64));
433 mem_bswap_64(data, size);
434}
435
436static void perf_event__all64_swap(union perf_event *event,
437 bool sample_id_all __maybe_unused)
438{
439 struct perf_event_header *hdr = &event->header;
440 mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr));
441}
442
443static void perf_event__comm_swap(union perf_event *event, bool sample_id_all)
444{
445 event->comm.pid = bswap_32(event->comm.pid);
446 event->comm.tid = bswap_32(event->comm.tid);
447
448 if (sample_id_all) {
449 void *data = &event->comm.comm;
450
451 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64));
452 swap_sample_id_all(event, data);
453 }
454}
455
456static void perf_event__mmap_swap(union perf_event *event,
457 bool sample_id_all)
458{
459 event->mmap.pid = bswap_32(event->mmap.pid);
460 event->mmap.tid = bswap_32(event->mmap.tid);
461 event->mmap.start = bswap_64(event->mmap.start);
462 event->mmap.len = bswap_64(event->mmap.len);
463 event->mmap.pgoff = bswap_64(event->mmap.pgoff);
464
465 if (sample_id_all) {
466 void *data = &event->mmap.filename;
467
468 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64));
469 swap_sample_id_all(event, data);
470 }
471}
472
473static void perf_event__mmap2_swap(union perf_event *event,
474 bool sample_id_all)
475{
476 event->mmap2.pid = bswap_32(event->mmap2.pid);
477 event->mmap2.tid = bswap_32(event->mmap2.tid);
478 event->mmap2.start = bswap_64(event->mmap2.start);
479 event->mmap2.len = bswap_64(event->mmap2.len);
480 event->mmap2.pgoff = bswap_64(event->mmap2.pgoff);
481 event->mmap2.maj = bswap_32(event->mmap2.maj);
482 event->mmap2.min = bswap_32(event->mmap2.min);
483 event->mmap2.ino = bswap_64(event->mmap2.ino);
484
485 if (sample_id_all) {
486 void *data = &event->mmap2.filename;
487
488 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64));
489 swap_sample_id_all(event, data);
490 }
491}
492static void perf_event__task_swap(union perf_event *event, bool sample_id_all)
493{
494 event->fork.pid = bswap_32(event->fork.pid);
495 event->fork.tid = bswap_32(event->fork.tid);
496 event->fork.ppid = bswap_32(event->fork.ppid);
497 event->fork.ptid = bswap_32(event->fork.ptid);
498 event->fork.time = bswap_64(event->fork.time);
499
500 if (sample_id_all)
501 swap_sample_id_all(event, &event->fork + 1);
502}
503
504static void perf_event__read_swap(union perf_event *event, bool sample_id_all)
505{
506 event->read.pid = bswap_32(event->read.pid);
507 event->read.tid = bswap_32(event->read.tid);
508 event->read.value = bswap_64(event->read.value);
509 event->read.time_enabled = bswap_64(event->read.time_enabled);
510 event->read.time_running = bswap_64(event->read.time_running);
511 event->read.id = bswap_64(event->read.id);
512
513 if (sample_id_all)
514 swap_sample_id_all(event, &event->read + 1);
515}
516
517static void perf_event__aux_swap(union perf_event *event, bool sample_id_all)
518{
519 event->aux.aux_offset = bswap_64(event->aux.aux_offset);
520 event->aux.aux_size = bswap_64(event->aux.aux_size);
521 event->aux.flags = bswap_64(event->aux.flags);
522
523 if (sample_id_all)
524 swap_sample_id_all(event, &event->aux + 1);
525}
526
527static void perf_event__itrace_start_swap(union perf_event *event,
528 bool sample_id_all)
529{
530 event->itrace_start.pid = bswap_32(event->itrace_start.pid);
531 event->itrace_start.tid = bswap_32(event->itrace_start.tid);
532
533 if (sample_id_all)
534 swap_sample_id_all(event, &event->itrace_start + 1);
535}
536
537static void perf_event__switch_swap(union perf_event *event, bool sample_id_all)
538{
539 if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) {
540 event->context_switch.next_prev_pid =
541 bswap_32(event->context_switch.next_prev_pid);
542 event->context_switch.next_prev_tid =
543 bswap_32(event->context_switch.next_prev_tid);
544 }
545
546 if (sample_id_all)
547 swap_sample_id_all(event, &event->context_switch + 1);
548}
549
550static void perf_event__throttle_swap(union perf_event *event,
551 bool sample_id_all)
552{
553 event->throttle.time = bswap_64(event->throttle.time);
554 event->throttle.id = bswap_64(event->throttle.id);
555 event->throttle.stream_id = bswap_64(event->throttle.stream_id);
556
557 if (sample_id_all)
558 swap_sample_id_all(event, &event->throttle + 1);
559}
560
561static u8 revbyte(u8 b)
562{
563 int rev = (b >> 4) | ((b & 0xf) << 4);
564 rev = ((rev & 0xcc) >> 2) | ((rev & 0x33) << 2);
565 rev = ((rev & 0xaa) >> 1) | ((rev & 0x55) << 1);
566 return (u8) rev;
567}
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583static void swap_bitfield(u8 *p, unsigned len)
584{
585 unsigned i;
586
587 for (i = 0; i < len; i++) {
588 *p = revbyte(*p);
589 p++;
590 }
591}
592
593
594void perf_event__attr_swap(struct perf_event_attr *attr)
595{
596 attr->type = bswap_32(attr->type);
597 attr->size = bswap_32(attr->size);
598
599#define bswap_safe(f, n) \
600 (attr->size > (offsetof(struct perf_event_attr, f) + \
601 sizeof(attr->f) * (n)))
602#define bswap_field(f, sz) \
603do { \
604 if (bswap_safe(f, 0)) \
605 attr->f = bswap_##sz(attr->f); \
606} while(0)
607#define bswap_field_32(f) bswap_field(f, 32)
608#define bswap_field_64(f) bswap_field(f, 64)
609
610 bswap_field_64(config);
611 bswap_field_64(sample_period);
612 bswap_field_64(sample_type);
613 bswap_field_64(read_format);
614 bswap_field_32(wakeup_events);
615 bswap_field_32(bp_type);
616 bswap_field_64(bp_addr);
617 bswap_field_64(bp_len);
618 bswap_field_64(branch_sample_type);
619 bswap_field_64(sample_regs_user);
620 bswap_field_32(sample_stack_user);
621 bswap_field_32(aux_watermark);
622
623
624
625
626
627 if (bswap_safe(read_format, 1))
628 swap_bitfield((u8 *) (&attr->read_format + 1),
629 sizeof(u64));
630#undef bswap_field_64
631#undef bswap_field_32
632#undef bswap_field
633#undef bswap_safe
634}
635
636static void perf_event__hdr_attr_swap(union perf_event *event,
637 bool sample_id_all __maybe_unused)
638{
639 size_t size;
640
641 perf_event__attr_swap(&event->attr.attr);
642
643 size = event->header.size;
644 size -= (void *)&event->attr.id - (void *)event;
645 mem_bswap_64(event->attr.id, size);
646}
647
648static void perf_event__event_update_swap(union perf_event *event,
649 bool sample_id_all __maybe_unused)
650{
651 event->event_update.type = bswap_64(event->event_update.type);
652 event->event_update.id = bswap_64(event->event_update.id);
653}
654
655static void perf_event__event_type_swap(union perf_event *event,
656 bool sample_id_all __maybe_unused)
657{
658 event->event_type.event_type.event_id =
659 bswap_64(event->event_type.event_type.event_id);
660}
661
662static void perf_event__tracing_data_swap(union perf_event *event,
663 bool sample_id_all __maybe_unused)
664{
665 event->tracing_data.size = bswap_32(event->tracing_data.size);
666}
667
668static void perf_event__auxtrace_info_swap(union perf_event *event,
669 bool sample_id_all __maybe_unused)
670{
671 size_t size;
672
673 event->auxtrace_info.type = bswap_32(event->auxtrace_info.type);
674
675 size = event->header.size;
676 size -= (void *)&event->auxtrace_info.priv - (void *)event;
677 mem_bswap_64(event->auxtrace_info.priv, size);
678}
679
680static void perf_event__auxtrace_swap(union perf_event *event,
681 bool sample_id_all __maybe_unused)
682{
683 event->auxtrace.size = bswap_64(event->auxtrace.size);
684 event->auxtrace.offset = bswap_64(event->auxtrace.offset);
685 event->auxtrace.reference = bswap_64(event->auxtrace.reference);
686 event->auxtrace.idx = bswap_32(event->auxtrace.idx);
687 event->auxtrace.tid = bswap_32(event->auxtrace.tid);
688 event->auxtrace.cpu = bswap_32(event->auxtrace.cpu);
689}
690
691static void perf_event__auxtrace_error_swap(union perf_event *event,
692 bool sample_id_all __maybe_unused)
693{
694 event->auxtrace_error.type = bswap_32(event->auxtrace_error.type);
695 event->auxtrace_error.code = bswap_32(event->auxtrace_error.code);
696 event->auxtrace_error.cpu = bswap_32(event->auxtrace_error.cpu);
697 event->auxtrace_error.pid = bswap_32(event->auxtrace_error.pid);
698 event->auxtrace_error.tid = bswap_32(event->auxtrace_error.tid);
699 event->auxtrace_error.ip = bswap_64(event->auxtrace_error.ip);
700}
701
702static void perf_event__thread_map_swap(union perf_event *event,
703 bool sample_id_all __maybe_unused)
704{
705 unsigned i;
706
707 event->thread_map.nr = bswap_64(event->thread_map.nr);
708
709 for (i = 0; i < event->thread_map.nr; i++)
710 event->thread_map.entries[i].pid = bswap_64(event->thread_map.entries[i].pid);
711}
712
713static void perf_event__cpu_map_swap(union perf_event *event,
714 bool sample_id_all __maybe_unused)
715{
716 struct cpu_map_data *data = &event->cpu_map.data;
717 struct cpu_map_entries *cpus;
718 struct cpu_map_mask *mask;
719 unsigned i;
720
721 data->type = bswap_64(data->type);
722
723 switch (data->type) {
724 case PERF_CPU_MAP__CPUS:
725 cpus = (struct cpu_map_entries *)data->data;
726
727 cpus->nr = bswap_16(cpus->nr);
728
729 for (i = 0; i < cpus->nr; i++)
730 cpus->cpu[i] = bswap_16(cpus->cpu[i]);
731 break;
732 case PERF_CPU_MAP__MASK:
733 mask = (struct cpu_map_mask *) data->data;
734
735 mask->nr = bswap_16(mask->nr);
736 mask->long_size = bswap_16(mask->long_size);
737
738 switch (mask->long_size) {
739 case 4: mem_bswap_32(&mask->mask, mask->nr); break;
740 case 8: mem_bswap_64(&mask->mask, mask->nr); break;
741 default:
742 pr_err("cpu_map swap: unsupported long size\n");
743 }
744 default:
745 break;
746 }
747}
748
749static void perf_event__stat_config_swap(union perf_event *event,
750 bool sample_id_all __maybe_unused)
751{
752 u64 size;
753
754 size = event->stat_config.nr * sizeof(event->stat_config.data[0]);
755 size += 1;
756 mem_bswap_64(&event->stat_config.nr, size);
757}
758
759static void perf_event__stat_swap(union perf_event *event,
760 bool sample_id_all __maybe_unused)
761{
762 event->stat.id = bswap_64(event->stat.id);
763 event->stat.thread = bswap_32(event->stat.thread);
764 event->stat.cpu = bswap_32(event->stat.cpu);
765 event->stat.val = bswap_64(event->stat.val);
766 event->stat.ena = bswap_64(event->stat.ena);
767 event->stat.run = bswap_64(event->stat.run);
768}
769
770static void perf_event__stat_round_swap(union perf_event *event,
771 bool sample_id_all __maybe_unused)
772{
773 event->stat_round.type = bswap_64(event->stat_round.type);
774 event->stat_round.time = bswap_64(event->stat_round.time);
775}
776
777typedef void (*perf_event__swap_op)(union perf_event *event,
778 bool sample_id_all);
779
780static perf_event__swap_op perf_event__swap_ops[] = {
781 [PERF_RECORD_MMAP] = perf_event__mmap_swap,
782 [PERF_RECORD_MMAP2] = perf_event__mmap2_swap,
783 [PERF_RECORD_COMM] = perf_event__comm_swap,
784 [PERF_RECORD_FORK] = perf_event__task_swap,
785 [PERF_RECORD_EXIT] = perf_event__task_swap,
786 [PERF_RECORD_LOST] = perf_event__all64_swap,
787 [PERF_RECORD_READ] = perf_event__read_swap,
788 [PERF_RECORD_THROTTLE] = perf_event__throttle_swap,
789 [PERF_RECORD_UNTHROTTLE] = perf_event__throttle_swap,
790 [PERF_RECORD_SAMPLE] = perf_event__all64_swap,
791 [PERF_RECORD_AUX] = perf_event__aux_swap,
792 [PERF_RECORD_ITRACE_START] = perf_event__itrace_start_swap,
793 [PERF_RECORD_LOST_SAMPLES] = perf_event__all64_swap,
794 [PERF_RECORD_SWITCH] = perf_event__switch_swap,
795 [PERF_RECORD_SWITCH_CPU_WIDE] = perf_event__switch_swap,
796 [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap,
797 [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap,
798 [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
799 [PERF_RECORD_HEADER_BUILD_ID] = NULL,
800 [PERF_RECORD_ID_INDEX] = perf_event__all64_swap,
801 [PERF_RECORD_AUXTRACE_INFO] = perf_event__auxtrace_info_swap,
802 [PERF_RECORD_AUXTRACE] = perf_event__auxtrace_swap,
803 [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap,
804 [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap,
805 [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap,
806 [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap,
807 [PERF_RECORD_STAT] = perf_event__stat_swap,
808 [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap,
809 [PERF_RECORD_EVENT_UPDATE] = perf_event__event_update_swap,
810 [PERF_RECORD_TIME_CONV] = perf_event__all64_swap,
811 [PERF_RECORD_HEADER_MAX] = NULL,
812};
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853static int process_finished_round(struct perf_tool *tool __maybe_unused,
854 union perf_event *event __maybe_unused,
855 struct ordered_events *oe)
856{
857 if (dump_trace)
858 fprintf(stdout, "\n");
859 return ordered_events__flush(oe, OE_FLUSH__ROUND);
860}
861
862int perf_session__queue_event(struct perf_session *s, union perf_event *event,
863 u64 timestamp, u64 file_offset)
864{
865 return ordered_events__queue(&s->ordered_events, event, timestamp, file_offset);
866}
867
868static void callchain__lbr_callstack_printf(struct perf_sample *sample)
869{
870 struct ip_callchain *callchain = sample->callchain;
871 struct branch_stack *lbr_stack = sample->branch_stack;
872 u64 kernel_callchain_nr = callchain->nr;
873 unsigned int i;
874
875 for (i = 0; i < kernel_callchain_nr; i++) {
876 if (callchain->ips[i] == PERF_CONTEXT_USER)
877 break;
878 }
879
880 if ((i != kernel_callchain_nr) && lbr_stack->nr) {
881 u64 total_nr;
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898 total_nr = i + 1 + lbr_stack->nr + 1;
899 kernel_callchain_nr = i + 1;
900
901 printf("... LBR call chain: nr:%" PRIu64 "\n", total_nr);
902
903 for (i = 0; i < kernel_callchain_nr; i++)
904 printf("..... %2d: %016" PRIx64 "\n",
905 i, callchain->ips[i]);
906
907 printf("..... %2d: %016" PRIx64 "\n",
908 (int)(kernel_callchain_nr), lbr_stack->entries[0].to);
909 for (i = 0; i < lbr_stack->nr; i++)
910 printf("..... %2d: %016" PRIx64 "\n",
911 (int)(i + kernel_callchain_nr + 1), lbr_stack->entries[i].from);
912 }
913}
914
915static void callchain__printf(struct perf_evsel *evsel,
916 struct perf_sample *sample)
917{
918 unsigned int i;
919 struct ip_callchain *callchain = sample->callchain;
920
921 if (perf_evsel__has_branch_callstack(evsel))
922 callchain__lbr_callstack_printf(sample);
923
924 printf("... FP chain: nr:%" PRIu64 "\n", callchain->nr);
925
926 for (i = 0; i < callchain->nr; i++)
927 printf("..... %2d: %016" PRIx64 "\n",
928 i, callchain->ips[i]);
929}
930
931static void branch_stack__printf(struct perf_sample *sample)
932{
933 uint64_t i;
934
935 printf("... branch stack: nr:%" PRIu64 "\n", sample->branch_stack->nr);
936
937 for (i = 0; i < sample->branch_stack->nr; i++) {
938 struct branch_entry *e = &sample->branch_stack->entries[i];
939
940 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x\n",
941 i, e->from, e->to,
942 (unsigned short)e->flags.cycles,
943 e->flags.mispred ? "M" : " ",
944 e->flags.predicted ? "P" : " ",
945 e->flags.abort ? "A" : " ",
946 e->flags.in_tx ? "T" : " ",
947 (unsigned)e->flags.reserved);
948 }
949}
950
951static void regs_dump__printf(u64 mask, u64 *regs)
952{
953 unsigned rid, i = 0;
954
955 for_each_set_bit(rid, (unsigned long *) &mask, sizeof(mask) * 8) {
956 u64 val = regs[i++];
957
958 printf(".... %-5s 0x%" PRIx64 "\n",
959 perf_reg_name(rid), val);
960 }
961}
962
963static const char *regs_abi[] = {
964 [PERF_SAMPLE_REGS_ABI_NONE] = "none",
965 [PERF_SAMPLE_REGS_ABI_32] = "32-bit",
966 [PERF_SAMPLE_REGS_ABI_64] = "64-bit",
967};
968
969static inline const char *regs_dump_abi(struct regs_dump *d)
970{
971 if (d->abi > PERF_SAMPLE_REGS_ABI_64)
972 return "unknown";
973
974 return regs_abi[d->abi];
975}
976
977static void regs__printf(const char *type, struct regs_dump *regs)
978{
979 u64 mask = regs->mask;
980
981 printf("... %s regs: mask 0x%" PRIx64 " ABI %s\n",
982 type,
983 mask,
984 regs_dump_abi(regs));
985
986 regs_dump__printf(mask, regs->regs);
987}
988
989static void regs_user__printf(struct perf_sample *sample)
990{
991 struct regs_dump *user_regs = &sample->user_regs;
992
993 if (user_regs->regs)
994 regs__printf("user", user_regs);
995}
996
997static void regs_intr__printf(struct perf_sample *sample)
998{
999 struct regs_dump *intr_regs = &sample->intr_regs;
1000
1001 if (intr_regs->regs)
1002 regs__printf("intr", intr_regs);
1003}
1004
1005static void stack_user__printf(struct stack_dump *dump)
1006{
1007 printf("... ustack: size %" PRIu64 ", offset 0x%x\n",
1008 dump->size, dump->offset);
1009}
1010
1011static void perf_evlist__print_tstamp(struct perf_evlist *evlist,
1012 union perf_event *event,
1013 struct perf_sample *sample)
1014{
1015 u64 sample_type = __perf_evlist__combined_sample_type(evlist);
1016
1017 if (event->header.type != PERF_RECORD_SAMPLE &&
1018 !perf_evlist__sample_id_all(evlist)) {
1019 fputs("-1 -1 ", stdout);
1020 return;
1021 }
1022
1023 if ((sample_type & PERF_SAMPLE_CPU))
1024 printf("%u ", sample->cpu);
1025
1026 if (sample_type & PERF_SAMPLE_TIME)
1027 printf("%" PRIu64 " ", sample->time);
1028}
1029
1030static void sample_read__printf(struct perf_sample *sample, u64 read_format)
1031{
1032 printf("... sample_read:\n");
1033
1034 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1035 printf("...... time enabled %016" PRIx64 "\n",
1036 sample->read.time_enabled);
1037
1038 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
1039 printf("...... time running %016" PRIx64 "\n",
1040 sample->read.time_running);
1041
1042 if (read_format & PERF_FORMAT_GROUP) {
1043 u64 i;
1044
1045 printf(".... group nr %" PRIu64 "\n", sample->read.group.nr);
1046
1047 for (i = 0; i < sample->read.group.nr; i++) {
1048 struct sample_read_value *value;
1049
1050 value = &sample->read.group.values[i];
1051 printf("..... id %016" PRIx64
1052 ", value %016" PRIx64 "\n",
1053 value->id, value->value);
1054 }
1055 } else
1056 printf("..... id %016" PRIx64 ", value %016" PRIx64 "\n",
1057 sample->read.one.id, sample->read.one.value);
1058}
1059
1060static void dump_event(struct perf_evlist *evlist, union perf_event *event,
1061 u64 file_offset, struct perf_sample *sample)
1062{
1063 if (!dump_trace)
1064 return;
1065
1066 printf("\n%#" PRIx64 " [%#x]: event: %d\n",
1067 file_offset, event->header.size, event->header.type);
1068
1069 trace_event(event);
1070
1071 if (sample)
1072 perf_evlist__print_tstamp(evlist, event, sample);
1073
1074 printf("%#" PRIx64 " [%#x]: PERF_RECORD_%s", file_offset,
1075 event->header.size, perf_event__name(event->header.type));
1076}
1077
1078static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
1079 struct perf_sample *sample)
1080{
1081 u64 sample_type;
1082
1083 if (!dump_trace)
1084 return;
1085
1086 printf("(IP, 0x%x): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n",
1087 event->header.misc, sample->pid, sample->tid, sample->ip,
1088 sample->period, sample->addr);
1089
1090 sample_type = evsel->attr.sample_type;
1091
1092 if (sample_type & PERF_SAMPLE_CALLCHAIN)
1093 callchain__printf(evsel, sample);
1094
1095 if ((sample_type & PERF_SAMPLE_BRANCH_STACK) && !perf_evsel__has_branch_callstack(evsel))
1096 branch_stack__printf(sample);
1097
1098 if (sample_type & PERF_SAMPLE_REGS_USER)
1099 regs_user__printf(sample);
1100
1101 if (sample_type & PERF_SAMPLE_REGS_INTR)
1102 regs_intr__printf(sample);
1103
1104 if (sample_type & PERF_SAMPLE_STACK_USER)
1105 stack_user__printf(&sample->user_stack);
1106
1107 if (sample_type & PERF_SAMPLE_WEIGHT)
1108 printf("... weight: %" PRIu64 "\n", sample->weight);
1109
1110 if (sample_type & PERF_SAMPLE_DATA_SRC)
1111 printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
1112
1113 if (sample_type & PERF_SAMPLE_PHYS_ADDR)
1114 printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr);
1115
1116 if (sample_type & PERF_SAMPLE_TRANSACTION)
1117 printf("... transaction: %" PRIx64 "\n", sample->transaction);
1118
1119 if (sample_type & PERF_SAMPLE_READ)
1120 sample_read__printf(sample, evsel->attr.read_format);
1121}
1122
1123static void dump_read(struct perf_evsel *evsel, union perf_event *event)
1124{
1125 struct read_event *read_event = &event->read;
1126 u64 read_format;
1127
1128 if (!dump_trace)
1129 return;
1130
1131 printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid,
1132 evsel ? perf_evsel__name(evsel) : "FAIL",
1133 event->read.value);
1134
1135 read_format = evsel->attr.read_format;
1136
1137 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1138 printf("... time enabled : %" PRIu64 "\n", read_event->time_enabled);
1139
1140 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
1141 printf("... time running : %" PRIu64 "\n", read_event->time_running);
1142
1143 if (read_format & PERF_FORMAT_ID)
1144 printf("... id : %" PRIu64 "\n", read_event->id);
1145}
1146
1147static struct machine *machines__find_for_cpumode(struct machines *machines,
1148 union perf_event *event,
1149 struct perf_sample *sample)
1150{
1151 struct machine *machine;
1152
1153 if (perf_guest &&
1154 ((sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ||
1155 (sample->cpumode == PERF_RECORD_MISC_GUEST_USER))) {
1156 u32 pid;
1157
1158 if (event->header.type == PERF_RECORD_MMAP
1159 || event->header.type == PERF_RECORD_MMAP2)
1160 pid = event->mmap.pid;
1161 else
1162 pid = sample->pid;
1163
1164 machine = machines__find(machines, pid);
1165 if (!machine)
1166 machine = machines__findnew(machines, DEFAULT_GUEST_KERNEL_ID);
1167 return machine;
1168 }
1169
1170 return &machines->host;
1171}
1172
1173static int deliver_sample_value(struct perf_evlist *evlist,
1174 struct perf_tool *tool,
1175 union perf_event *event,
1176 struct perf_sample *sample,
1177 struct sample_read_value *v,
1178 struct machine *machine)
1179{
1180 struct perf_sample_id *sid = perf_evlist__id2sid(evlist, v->id);
1181
1182 if (sid) {
1183 sample->id = v->id;
1184 sample->period = v->value - sid->period;
1185 sid->period = v->value;
1186 }
1187
1188 if (!sid || sid->evsel == NULL) {
1189 ++evlist->stats.nr_unknown_id;
1190 return 0;
1191 }
1192
1193 return tool->sample(tool, event, sample, sid->evsel, machine);
1194}
1195
1196static int deliver_sample_group(struct perf_evlist *evlist,
1197 struct perf_tool *tool,
1198 union perf_event *event,
1199 struct perf_sample *sample,
1200 struct machine *machine)
1201{
1202 int ret = -EINVAL;
1203 u64 i;
1204
1205 for (i = 0; i < sample->read.group.nr; i++) {
1206 ret = deliver_sample_value(evlist, tool, event, sample,
1207 &sample->read.group.values[i],
1208 machine);
1209 if (ret)
1210 break;
1211 }
1212
1213 return ret;
1214}
1215
1216static int
1217 perf_evlist__deliver_sample(struct perf_evlist *evlist,
1218 struct perf_tool *tool,
1219 union perf_event *event,
1220 struct perf_sample *sample,
1221 struct perf_evsel *evsel,
1222 struct machine *machine)
1223{
1224
1225 u64 sample_type = evsel->attr.sample_type;
1226 u64 read_format = evsel->attr.read_format;
1227
1228
1229 if (!(sample_type & PERF_SAMPLE_READ))
1230 return tool->sample(tool, event, sample, evsel, machine);
1231
1232
1233 if (read_format & PERF_FORMAT_GROUP)
1234 return deliver_sample_group(evlist, tool, event, sample,
1235 machine);
1236 else
1237 return deliver_sample_value(evlist, tool, event, sample,
1238 &sample->read.one, machine);
1239}
1240
1241static int machines__deliver_event(struct machines *machines,
1242 struct perf_evlist *evlist,
1243 union perf_event *event,
1244 struct perf_sample *sample,
1245 struct perf_tool *tool, u64 file_offset)
1246{
1247 struct perf_evsel *evsel;
1248 struct machine *machine;
1249
1250 dump_event(evlist, event, file_offset, sample);
1251
1252 evsel = perf_evlist__id2evsel(evlist, sample->id);
1253
1254 machine = machines__find_for_cpumode(machines, event, sample);
1255
1256 switch (event->header.type) {
1257 case PERF_RECORD_SAMPLE:
1258 if (evsel == NULL) {
1259 ++evlist->stats.nr_unknown_id;
1260 return 0;
1261 }
1262 dump_sample(evsel, event, sample);
1263 if (machine == NULL) {
1264 ++evlist->stats.nr_unprocessable_samples;
1265 return 0;
1266 }
1267 return perf_evlist__deliver_sample(evlist, tool, event, sample, evsel, machine);
1268 case PERF_RECORD_MMAP:
1269 return tool->mmap(tool, event, sample, machine);
1270 case PERF_RECORD_MMAP2:
1271 if (event->header.misc & PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT)
1272 ++evlist->stats.nr_proc_map_timeout;
1273 return tool->mmap2(tool, event, sample, machine);
1274 case PERF_RECORD_COMM:
1275 return tool->comm(tool, event, sample, machine);
1276 case PERF_RECORD_FORK:
1277 return tool->fork(tool, event, sample, machine);
1278 case PERF_RECORD_EXIT:
1279 return tool->exit(tool, event, sample, machine);
1280 case PERF_RECORD_LOST:
1281 if (tool->lost == perf_event__process_lost)
1282 evlist->stats.total_lost += event->lost.lost;
1283 return tool->lost(tool, event, sample, machine);
1284 case PERF_RECORD_LOST_SAMPLES:
1285 if (tool->lost_samples == perf_event__process_lost_samples)
1286 evlist->stats.total_lost_samples += event->lost_samples.lost;
1287 return tool->lost_samples(tool, event, sample, machine);
1288 case PERF_RECORD_READ:
1289 dump_read(evsel, event);
1290 return tool->read(tool, event, sample, evsel, machine);
1291 case PERF_RECORD_THROTTLE:
1292 return tool->throttle(tool, event, sample, machine);
1293 case PERF_RECORD_UNTHROTTLE:
1294 return tool->unthrottle(tool, event, sample, machine);
1295 case PERF_RECORD_AUX:
1296 if (tool->aux == perf_event__process_aux) {
1297 if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
1298 evlist->stats.total_aux_lost += 1;
1299 if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
1300 evlist->stats.total_aux_partial += 1;
1301 }
1302 return tool->aux(tool, event, sample, machine);
1303 case PERF_RECORD_ITRACE_START:
1304 return tool->itrace_start(tool, event, sample, machine);
1305 case PERF_RECORD_SWITCH:
1306 case PERF_RECORD_SWITCH_CPU_WIDE:
1307 return tool->context_switch(tool, event, sample, machine);
1308 default:
1309 ++evlist->stats.nr_unknown_events;
1310 return -1;
1311 }
1312}
1313
1314static int perf_session__deliver_event(struct perf_session *session,
1315 union perf_event *event,
1316 struct perf_tool *tool,
1317 u64 file_offset)
1318{
1319 struct perf_sample sample;
1320 int ret;
1321
1322 ret = perf_evlist__parse_sample(session->evlist, event, &sample);
1323 if (ret) {
1324 pr_err("Can't parse sample, err = %d\n", ret);
1325 return ret;
1326 }
1327
1328 ret = auxtrace__process_event(session, event, &sample, tool);
1329 if (ret < 0)
1330 return ret;
1331 if (ret > 0)
1332 return 0;
1333
1334 return machines__deliver_event(&session->machines, session->evlist,
1335 event, &sample, tool, file_offset);
1336}
1337
1338static s64 perf_session__process_user_event(struct perf_session *session,
1339 union perf_event *event,
1340 u64 file_offset)
1341{
1342 struct ordered_events *oe = &session->ordered_events;
1343 struct perf_tool *tool = session->tool;
1344 int fd = perf_data__fd(session->data);
1345 int err;
1346
1347 dump_event(session->evlist, event, file_offset, NULL);
1348
1349
1350 switch (event->header.type) {
1351 case PERF_RECORD_HEADER_ATTR:
1352 err = tool->attr(tool, event, &session->evlist);
1353 if (err == 0) {
1354 perf_session__set_id_hdr_size(session);
1355 perf_session__set_comm_exec(session);
1356 }
1357 return err;
1358 case PERF_RECORD_EVENT_UPDATE:
1359 return tool->event_update(tool, event, &session->evlist);
1360 case PERF_RECORD_HEADER_EVENT_TYPE:
1361
1362
1363
1364
1365 return 0;
1366 case PERF_RECORD_HEADER_TRACING_DATA:
1367
1368 lseek(fd, file_offset, SEEK_SET);
1369 return tool->tracing_data(tool, event, session);
1370 case PERF_RECORD_HEADER_BUILD_ID:
1371 return tool->build_id(tool, event, session);
1372 case PERF_RECORD_FINISHED_ROUND:
1373 return tool->finished_round(tool, event, oe);
1374 case PERF_RECORD_ID_INDEX:
1375 return tool->id_index(tool, event, session);
1376 case PERF_RECORD_AUXTRACE_INFO:
1377 return tool->auxtrace_info(tool, event, session);
1378 case PERF_RECORD_AUXTRACE:
1379
1380 lseek(fd, file_offset + event->header.size, SEEK_SET);
1381 return tool->auxtrace(tool, event, session);
1382 case PERF_RECORD_AUXTRACE_ERROR:
1383 perf_session__auxtrace_error_inc(session, event);
1384 return tool->auxtrace_error(tool, event, session);
1385 case PERF_RECORD_THREAD_MAP:
1386 return tool->thread_map(tool, event, session);
1387 case PERF_RECORD_CPU_MAP:
1388 return tool->cpu_map(tool, event, session);
1389 case PERF_RECORD_STAT_CONFIG:
1390 return tool->stat_config(tool, event, session);
1391 case PERF_RECORD_STAT:
1392 return tool->stat(tool, event, session);
1393 case PERF_RECORD_STAT_ROUND:
1394 return tool->stat_round(tool, event, session);
1395 case PERF_RECORD_TIME_CONV:
1396 session->time_conv = event->time_conv;
1397 return tool->time_conv(tool, event, session);
1398 case PERF_RECORD_HEADER_FEATURE:
1399 return tool->feature(tool, event, session);
1400 default:
1401 return -EINVAL;
1402 }
1403}
1404
1405int perf_session__deliver_synth_event(struct perf_session *session,
1406 union perf_event *event,
1407 struct perf_sample *sample)
1408{
1409 struct perf_evlist *evlist = session->evlist;
1410 struct perf_tool *tool = session->tool;
1411
1412 events_stats__inc(&evlist->stats, event->header.type);
1413
1414 if (event->header.type >= PERF_RECORD_USER_TYPE_START)
1415 return perf_session__process_user_event(session, event, 0);
1416
1417 return machines__deliver_event(&session->machines, evlist, event, sample, tool, 0);
1418}
1419
1420static void event_swap(union perf_event *event, bool sample_id_all)
1421{
1422 perf_event__swap_op swap;
1423
1424 swap = perf_event__swap_ops[event->header.type];
1425 if (swap)
1426 swap(event, sample_id_all);
1427}
1428
1429int perf_session__peek_event(struct perf_session *session, off_t file_offset,
1430 void *buf, size_t buf_sz,
1431 union perf_event **event_ptr,
1432 struct perf_sample *sample)
1433{
1434 union perf_event *event;
1435 size_t hdr_sz, rest;
1436 int fd;
1437
1438 if (session->one_mmap && !session->header.needs_swap) {
1439 event = file_offset - session->one_mmap_offset +
1440 session->one_mmap_addr;
1441 goto out_parse_sample;
1442 }
1443
1444 if (perf_data__is_pipe(session->data))
1445 return -1;
1446
1447 fd = perf_data__fd(session->data);
1448 hdr_sz = sizeof(struct perf_event_header);
1449
1450 if (buf_sz < hdr_sz)
1451 return -1;
1452
1453 if (lseek(fd, file_offset, SEEK_SET) == (off_t)-1 ||
1454 readn(fd, buf, hdr_sz) != (ssize_t)hdr_sz)
1455 return -1;
1456
1457 event = (union perf_event *)buf;
1458
1459 if (session->header.needs_swap)
1460 perf_event_header__bswap(&event->header);
1461
1462 if (event->header.size < hdr_sz || event->header.size > buf_sz)
1463 return -1;
1464
1465 rest = event->header.size - hdr_sz;
1466
1467 if (readn(fd, buf, rest) != (ssize_t)rest)
1468 return -1;
1469
1470 if (session->header.needs_swap)
1471 event_swap(event, perf_evlist__sample_id_all(session->evlist));
1472
1473out_parse_sample:
1474
1475 if (sample && event->header.type < PERF_RECORD_USER_TYPE_START &&
1476 perf_evlist__parse_sample(session->evlist, event, sample))
1477 return -1;
1478
1479 *event_ptr = event;
1480
1481 return 0;
1482}
1483
1484static s64 perf_session__process_event(struct perf_session *session,
1485 union perf_event *event, u64 file_offset)
1486{
1487 struct perf_evlist *evlist = session->evlist;
1488 struct perf_tool *tool = session->tool;
1489 int ret;
1490
1491 if (session->header.needs_swap)
1492 event_swap(event, perf_evlist__sample_id_all(evlist));
1493
1494 if (event->header.type >= PERF_RECORD_HEADER_MAX)
1495 return -EINVAL;
1496
1497 events_stats__inc(&evlist->stats, event->header.type);
1498
1499 if (event->header.type >= PERF_RECORD_USER_TYPE_START)
1500 return perf_session__process_user_event(session, event, file_offset);
1501
1502 if (tool->ordered_events) {
1503 u64 timestamp = -1ULL;
1504
1505 ret = perf_evlist__parse_sample_timestamp(evlist, event, ×tamp);
1506 if (ret && ret != -1)
1507 return ret;
1508
1509 ret = perf_session__queue_event(session, event, timestamp, file_offset);
1510 if (ret != -ETIME)
1511 return ret;
1512 }
1513
1514 return perf_session__deliver_event(session, event, tool, file_offset);
1515}
1516
1517void perf_event_header__bswap(struct perf_event_header *hdr)
1518{
1519 hdr->type = bswap_32(hdr->type);
1520 hdr->misc = bswap_16(hdr->misc);
1521 hdr->size = bswap_16(hdr->size);
1522}
1523
1524struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
1525{
1526 return machine__findnew_thread(&session->machines.host, -1, pid);
1527}
1528
1529int perf_session__register_idle_thread(struct perf_session *session)
1530{
1531 struct thread *thread;
1532 int err = 0;
1533
1534 thread = machine__findnew_thread(&session->machines.host, 0, 0);
1535 if (thread == NULL || thread__set_comm(thread, "swapper", 0)) {
1536 pr_err("problem inserting idle task.\n");
1537 err = -1;
1538 }
1539
1540
1541 thread__put(thread);
1542 return err;
1543}
1544
1545static void
1546perf_session__warn_order(const struct perf_session *session)
1547{
1548 const struct ordered_events *oe = &session->ordered_events;
1549 struct perf_evsel *evsel;
1550 bool should_warn = true;
1551
1552 evlist__for_each_entry(session->evlist, evsel) {
1553 if (evsel->attr.write_backward)
1554 should_warn = false;
1555 }
1556
1557 if (!should_warn)
1558 return;
1559 if (oe->nr_unordered_events != 0)
1560 ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events);
1561}
1562
1563static void perf_session__warn_about_errors(const struct perf_session *session)
1564{
1565 const struct events_stats *stats = &session->evlist->stats;
1566
1567 if (session->tool->lost == perf_event__process_lost &&
1568 stats->nr_events[PERF_RECORD_LOST] != 0) {
1569 ui__warning("Processed %d events and lost %d chunks!\n\n"
1570 "Check IO/CPU overload!\n\n",
1571 stats->nr_events[0],
1572 stats->nr_events[PERF_RECORD_LOST]);
1573 }
1574
1575 if (session->tool->lost_samples == perf_event__process_lost_samples) {
1576 double drop_rate;
1577
1578 drop_rate = (double)stats->total_lost_samples /
1579 (double) (stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples);
1580 if (drop_rate > 0.05) {
1581 ui__warning("Processed %" PRIu64 " samples and lost %3.2f%% samples!\n\n",
1582 stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples,
1583 drop_rate * 100.0);
1584 }
1585 }
1586
1587 if (session->tool->aux == perf_event__process_aux &&
1588 stats->total_aux_lost != 0) {
1589 ui__warning("AUX data lost %" PRIu64 " times out of %u!\n\n",
1590 stats->total_aux_lost,
1591 stats->nr_events[PERF_RECORD_AUX]);
1592 }
1593
1594 if (session->tool->aux == perf_event__process_aux &&
1595 stats->total_aux_partial != 0) {
1596 bool vmm_exclusive = false;
1597
1598 (void)sysfs__read_bool("module/kvm_intel/parameters/vmm_exclusive",
1599 &vmm_exclusive);
1600
1601 ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
1602 "Are you running a KVM guest in the background?%s\n\n",
1603 stats->total_aux_partial,
1604 stats->nr_events[PERF_RECORD_AUX],
1605 vmm_exclusive ?
1606 "\nReloading kvm_intel module with vmm_exclusive=0\n"
1607 "will reduce the gaps to only guest's timeslices." :
1608 "");
1609 }
1610
1611 if (stats->nr_unknown_events != 0) {
1612 ui__warning("Found %u unknown events!\n\n"
1613 "Is this an older tool processing a perf.data "
1614 "file generated by a more recent tool?\n\n"
1615 "If that is not the case, consider "
1616 "reporting to linux-kernel@vger.kernel.org.\n\n",
1617 stats->nr_unknown_events);
1618 }
1619
1620 if (stats->nr_unknown_id != 0) {
1621 ui__warning("%u samples with id not present in the header\n",
1622 stats->nr_unknown_id);
1623 }
1624
1625 if (stats->nr_invalid_chains != 0) {
1626 ui__warning("Found invalid callchains!\n\n"
1627 "%u out of %u events were discarded for this reason.\n\n"
1628 "Consider reporting to linux-kernel@vger.kernel.org.\n\n",
1629 stats->nr_invalid_chains,
1630 stats->nr_events[PERF_RECORD_SAMPLE]);
1631 }
1632
1633 if (stats->nr_unprocessable_samples != 0) {
1634 ui__warning("%u unprocessable samples recorded.\n"
1635 "Do you have a KVM guest running and not using 'perf kvm'?\n",
1636 stats->nr_unprocessable_samples);
1637 }
1638
1639 perf_session__warn_order(session);
1640
1641 events_stats__auxtrace_error_warn(stats);
1642
1643 if (stats->nr_proc_map_timeout != 0) {
1644 ui__warning("%d map information files for pre-existing threads were\n"
1645 "not processed, if there are samples for addresses they\n"
1646 "will not be resolved, you may find out which are these\n"
1647 "threads by running with -v and redirecting the output\n"
1648 "to a file.\n"
1649 "The time limit to process proc map is too short?\n"
1650 "Increase it by --proc-map-timeout\n",
1651 stats->nr_proc_map_timeout);
1652 }
1653}
1654
1655static int perf_session__flush_thread_stack(struct thread *thread,
1656 void *p __maybe_unused)
1657{
1658 return thread_stack__flush(thread);
1659}
1660
1661static int perf_session__flush_thread_stacks(struct perf_session *session)
1662{
1663 return machines__for_each_thread(&session->machines,
1664 perf_session__flush_thread_stack,
1665 NULL);
1666}
1667
1668volatile int session_done;
1669
1670static int __perf_session__process_pipe_events(struct perf_session *session)
1671{
1672 struct ordered_events *oe = &session->ordered_events;
1673 struct perf_tool *tool = session->tool;
1674 int fd = perf_data__fd(session->data);
1675 union perf_event *event;
1676 uint32_t size, cur_size = 0;
1677 void *buf = NULL;
1678 s64 skip = 0;
1679 u64 head;
1680 ssize_t err;
1681 void *p;
1682
1683 perf_tool__fill_defaults(tool);
1684
1685 head = 0;
1686 cur_size = sizeof(union perf_event);
1687
1688 buf = malloc(cur_size);
1689 if (!buf)
1690 return -errno;
1691 ordered_events__set_copy_on_queue(oe, true);
1692more:
1693 event = buf;
1694 err = readn(fd, event, sizeof(struct perf_event_header));
1695 if (err <= 0) {
1696 if (err == 0)
1697 goto done;
1698
1699 pr_err("failed to read event header\n");
1700 goto out_err;
1701 }
1702
1703 if (session->header.needs_swap)
1704 perf_event_header__bswap(&event->header);
1705
1706 size = event->header.size;
1707 if (size < sizeof(struct perf_event_header)) {
1708 pr_err("bad event header size\n");
1709 goto out_err;
1710 }
1711
1712 if (size > cur_size) {
1713 void *new = realloc(buf, size);
1714 if (!new) {
1715 pr_err("failed to allocate memory to read event\n");
1716 goto out_err;
1717 }
1718 buf = new;
1719 cur_size = size;
1720 event = buf;
1721 }
1722 p = event;
1723 p += sizeof(struct perf_event_header);
1724
1725 if (size - sizeof(struct perf_event_header)) {
1726 err = readn(fd, p, size - sizeof(struct perf_event_header));
1727 if (err <= 0) {
1728 if (err == 0) {
1729 pr_err("unexpected end of event stream\n");
1730 goto done;
1731 }
1732
1733 pr_err("failed to read event data\n");
1734 goto out_err;
1735 }
1736 }
1737
1738 if ((skip = perf_session__process_event(session, event, head)) < 0) {
1739 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
1740 head, event->header.size, event->header.type);
1741 err = -EINVAL;
1742 goto out_err;
1743 }
1744
1745 head += size;
1746
1747 if (skip > 0)
1748 head += skip;
1749
1750 if (!session_done())
1751 goto more;
1752done:
1753
1754 err = ordered_events__flush(oe, OE_FLUSH__FINAL);
1755 if (err)
1756 goto out_err;
1757 err = auxtrace__flush_events(session, tool);
1758 if (err)
1759 goto out_err;
1760 err = perf_session__flush_thread_stacks(session);
1761out_err:
1762 free(buf);
1763 perf_session__warn_about_errors(session);
1764 ordered_events__free(&session->ordered_events);
1765 auxtrace__free_events(session);
1766 return err;
1767}
1768
1769static union perf_event *
1770fetch_mmaped_event(struct perf_session *session,
1771 u64 head, size_t mmap_size, char *buf)
1772{
1773 union perf_event *event;
1774
1775
1776
1777
1778
1779 if (head + sizeof(event->header) > mmap_size)
1780 return NULL;
1781
1782 event = (union perf_event *)(buf + head);
1783
1784 if (session->header.needs_swap)
1785 perf_event_header__bswap(&event->header);
1786
1787 if (head + event->header.size > mmap_size) {
1788
1789 if (session->header.needs_swap)
1790 perf_event_header__bswap(&event->header);
1791 return NULL;
1792 }
1793
1794 return event;
1795}
1796
1797
1798
1799
1800
1801#if BITS_PER_LONG == 64
1802#define MMAP_SIZE ULLONG_MAX
1803#define NUM_MMAPS 1
1804#else
1805#define MMAP_SIZE (32 * 1024 * 1024ULL)
1806#define NUM_MMAPS 128
1807#endif
1808
1809static int __perf_session__process_events(struct perf_session *session,
1810 u64 data_offset, u64 data_size,
1811 u64 file_size)
1812{
1813 struct ordered_events *oe = &session->ordered_events;
1814 struct perf_tool *tool = session->tool;
1815 int fd = perf_data__fd(session->data);
1816 u64 head, page_offset, file_offset, file_pos, size;
1817 int err, mmap_prot, mmap_flags, map_idx = 0;
1818 size_t mmap_size;
1819 char *buf, *mmaps[NUM_MMAPS];
1820 union perf_event *event;
1821 struct ui_progress prog;
1822 s64 skip;
1823
1824 perf_tool__fill_defaults(tool);
1825
1826 page_offset = page_size * (data_offset / page_size);
1827 file_offset = page_offset;
1828 head = data_offset - page_offset;
1829
1830 if (data_size == 0)
1831 goto out;
1832
1833 if (data_offset + data_size < file_size)
1834 file_size = data_offset + data_size;
1835
1836 ui_progress__init_size(&prog, file_size, "Processing events...");
1837
1838 mmap_size = MMAP_SIZE;
1839 if (mmap_size > file_size) {
1840 mmap_size = file_size;
1841 session->one_mmap = true;
1842 }
1843
1844 memset(mmaps, 0, sizeof(mmaps));
1845
1846 mmap_prot = PROT_READ;
1847 mmap_flags = MAP_SHARED;
1848
1849 if (session->header.needs_swap) {
1850 mmap_prot |= PROT_WRITE;
1851 mmap_flags = MAP_PRIVATE;
1852 }
1853remap:
1854 buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, fd,
1855 file_offset);
1856 if (buf == MAP_FAILED) {
1857 pr_err("failed to mmap file\n");
1858 err = -errno;
1859 goto out_err;
1860 }
1861 mmaps[map_idx] = buf;
1862 map_idx = (map_idx + 1) & (ARRAY_SIZE(mmaps) - 1);
1863 file_pos = file_offset + head;
1864 if (session->one_mmap) {
1865 session->one_mmap_addr = buf;
1866 session->one_mmap_offset = file_offset;
1867 }
1868
1869more:
1870 event = fetch_mmaped_event(session, head, mmap_size, buf);
1871 if (!event) {
1872 if (mmaps[map_idx]) {
1873 munmap(mmaps[map_idx], mmap_size);
1874 mmaps[map_idx] = NULL;
1875 }
1876
1877 page_offset = page_size * (head / page_size);
1878 file_offset += page_offset;
1879 head -= page_offset;
1880 goto remap;
1881 }
1882
1883 size = event->header.size;
1884
1885 if (size < sizeof(struct perf_event_header) ||
1886 (skip = perf_session__process_event(session, event, file_pos)) < 0) {
1887 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
1888 file_offset + head, event->header.size,
1889 event->header.type);
1890 err = -EINVAL;
1891 goto out_err;
1892 }
1893
1894 if (skip)
1895 size += skip;
1896
1897 head += size;
1898 file_pos += size;
1899
1900 ui_progress__update(&prog, size);
1901
1902 if (session_done())
1903 goto out;
1904
1905 if (file_pos < file_size)
1906 goto more;
1907
1908out:
1909
1910 err = ordered_events__flush(oe, OE_FLUSH__FINAL);
1911 if (err)
1912 goto out_err;
1913 err = auxtrace__flush_events(session, tool);
1914 if (err)
1915 goto out_err;
1916 err = perf_session__flush_thread_stacks(session);
1917out_err:
1918 ui_progress__finish();
1919 perf_session__warn_about_errors(session);
1920
1921
1922
1923
1924 ordered_events__reinit(&session->ordered_events);
1925 auxtrace__free_events(session);
1926 session->one_mmap = false;
1927 return err;
1928}
1929
1930int perf_session__process_events(struct perf_session *session)
1931{
1932 u64 size = perf_data__size(session->data);
1933 int err;
1934
1935 if (perf_session__register_idle_thread(session) < 0)
1936 return -ENOMEM;
1937
1938 if (!perf_data__is_pipe(session->data))
1939 err = __perf_session__process_events(session,
1940 session->header.data_offset,
1941 session->header.data_size, size);
1942 else
1943 err = __perf_session__process_pipe_events(session);
1944
1945 return err;
1946}
1947
1948bool perf_session__has_traces(struct perf_session *session, const char *msg)
1949{
1950 struct perf_evsel *evsel;
1951
1952 evlist__for_each_entry(session->evlist, evsel) {
1953 if (evsel->attr.type == PERF_TYPE_TRACEPOINT)
1954 return true;
1955 }
1956
1957 pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg);
1958 return false;
1959}
1960
1961int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
1962 const char *symbol_name, u64 addr)
1963{
1964 char *bracket;
1965 int i;
1966 struct ref_reloc_sym *ref;
1967
1968 ref = zalloc(sizeof(struct ref_reloc_sym));
1969 if (ref == NULL)
1970 return -ENOMEM;
1971
1972 ref->name = strdup(symbol_name);
1973 if (ref->name == NULL) {
1974 free(ref);
1975 return -ENOMEM;
1976 }
1977
1978 bracket = strchr(ref->name, ']');
1979 if (bracket)
1980 *bracket = '\0';
1981
1982 ref->addr = addr;
1983
1984 for (i = 0; i < MAP__NR_TYPES; ++i) {
1985 struct kmap *kmap = map__kmap(maps[i]);
1986
1987 if (!kmap)
1988 continue;
1989 kmap->ref_reloc_sym = ref;
1990 }
1991
1992 return 0;
1993}
1994
1995size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp)
1996{
1997 return machines__fprintf_dsos(&session->machines, fp);
1998}
1999
2000size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp,
2001 bool (skip)(struct dso *dso, int parm), int parm)
2002{
2003 return machines__fprintf_dsos_buildid(&session->machines, fp, skip, parm);
2004}
2005
2006size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
2007{
2008 size_t ret;
2009 const char *msg = "";
2010
2011 if (perf_header__has_feat(&session->header, HEADER_AUXTRACE))
2012 msg = " (excludes AUX area (e.g. instruction trace) decoded / synthesized events)";
2013
2014 ret = fprintf(fp, "\nAggregated stats:%s\n", msg);
2015
2016 ret += events_stats__fprintf(&session->evlist->stats, fp);
2017 return ret;
2018}
2019
2020size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
2021{
2022
2023
2024
2025
2026 return machine__fprintf(&session->machines.host, fp);
2027}
2028
2029struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
2030 unsigned int type)
2031{
2032 struct perf_evsel *pos;
2033
2034 evlist__for_each_entry(session->evlist, pos) {
2035 if (pos->attr.type == type)
2036 return pos;
2037 }
2038 return NULL;
2039}
2040
2041int perf_session__cpu_bitmap(struct perf_session *session,
2042 const char *cpu_list, unsigned long *cpu_bitmap)
2043{
2044 int i, err = -1;
2045 struct cpu_map *map;
2046
2047 for (i = 0; i < PERF_TYPE_MAX; ++i) {
2048 struct perf_evsel *evsel;
2049
2050 evsel = perf_session__find_first_evtype(session, i);
2051 if (!evsel)
2052 continue;
2053
2054 if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) {
2055 pr_err("File does not contain CPU events. "
2056 "Remove -C option to proceed.\n");
2057 return -1;
2058 }
2059 }
2060
2061 map = cpu_map__new(cpu_list);
2062 if (map == NULL) {
2063 pr_err("Invalid cpu_list\n");
2064 return -1;
2065 }
2066
2067 for (i = 0; i < map->nr; i++) {
2068 int cpu = map->map[i];
2069
2070 if (cpu >= MAX_NR_CPUS) {
2071 pr_err("Requested CPU %d too large. "
2072 "Consider raising MAX_NR_CPUS\n", cpu);
2073 goto out_delete_map;
2074 }
2075
2076 set_bit(cpu, cpu_bitmap);
2077 }
2078
2079 err = 0;
2080
2081out_delete_map:
2082 cpu_map__put(map);
2083 return err;
2084}
2085
2086void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
2087 bool full)
2088{
2089 if (session == NULL || fp == NULL)
2090 return;
2091
2092 fprintf(fp, "# ========\n");
2093 perf_header__fprintf_info(session, fp, full);
2094 fprintf(fp, "# ========\n#\n");
2095}
2096
2097
2098int __perf_session__set_tracepoints_handlers(struct perf_session *session,
2099 const struct perf_evsel_str_handler *assocs,
2100 size_t nr_assocs)
2101{
2102 struct perf_evsel *evsel;
2103 size_t i;
2104 int err;
2105
2106 for (i = 0; i < nr_assocs; i++) {
2107
2108
2109
2110
2111 evsel = perf_evlist__find_tracepoint_by_name(session->evlist, assocs[i].name);
2112 if (evsel == NULL)
2113 continue;
2114
2115 err = -EEXIST;
2116 if (evsel->handler != NULL)
2117 goto out;
2118 evsel->handler = assocs[i].handler;
2119 }
2120
2121 err = 0;
2122out:
2123 return err;
2124}
2125
2126int perf_event__process_id_index(struct perf_tool *tool __maybe_unused,
2127 union perf_event *event,
2128 struct perf_session *session)
2129{
2130 struct perf_evlist *evlist = session->evlist;
2131 struct id_index_event *ie = &event->id_index;
2132 size_t i, nr, max_nr;
2133
2134 max_nr = (ie->header.size - sizeof(struct id_index_event)) /
2135 sizeof(struct id_index_entry);
2136 nr = ie->nr;
2137 if (nr > max_nr)
2138 return -EINVAL;
2139
2140 if (dump_trace)
2141 fprintf(stdout, " nr: %zu\n", nr);
2142
2143 for (i = 0; i < nr; i++) {
2144 struct id_index_entry *e = &ie->entries[i];
2145 struct perf_sample_id *sid;
2146
2147 if (dump_trace) {
2148 fprintf(stdout, " ... id: %"PRIu64, e->id);
2149 fprintf(stdout, " idx: %"PRIu64, e->idx);
2150 fprintf(stdout, " cpu: %"PRId64, e->cpu);
2151 fprintf(stdout, " tid: %"PRId64"\n", e->tid);
2152 }
2153
2154 sid = perf_evlist__id2sid(evlist, e->id);
2155 if (!sid)
2156 return -ENOENT;
2157 sid->idx = e->idx;
2158 sid->cpu = e->cpu;
2159 sid->tid = e->tid;
2160 }
2161 return 0;
2162}
2163
2164int perf_event__synthesize_id_index(struct perf_tool *tool,
2165 perf_event__handler_t process,
2166 struct perf_evlist *evlist,
2167 struct machine *machine)
2168{
2169 union perf_event *ev;
2170 struct perf_evsel *evsel;
2171 size_t nr = 0, i = 0, sz, max_nr, n;
2172 int err;
2173
2174 pr_debug2("Synthesizing id index\n");
2175
2176 max_nr = (UINT16_MAX - sizeof(struct id_index_event)) /
2177 sizeof(struct id_index_entry);
2178
2179 evlist__for_each_entry(evlist, evsel)
2180 nr += evsel->ids;
2181
2182 n = nr > max_nr ? max_nr : nr;
2183 sz = sizeof(struct id_index_event) + n * sizeof(struct id_index_entry);
2184 ev = zalloc(sz);
2185 if (!ev)
2186 return -ENOMEM;
2187
2188 ev->id_index.header.type = PERF_RECORD_ID_INDEX;
2189 ev->id_index.header.size = sz;
2190 ev->id_index.nr = n;
2191
2192 evlist__for_each_entry(evlist, evsel) {
2193 u32 j;
2194
2195 for (j = 0; j < evsel->ids; j++) {
2196 struct id_index_entry *e;
2197 struct perf_sample_id *sid;
2198
2199 if (i >= n) {
2200 err = process(tool, ev, NULL, machine);
2201 if (err)
2202 goto out_err;
2203 nr -= n;
2204 i = 0;
2205 }
2206
2207 e = &ev->id_index.entries[i++];
2208
2209 e->id = evsel->id[j];
2210
2211 sid = perf_evlist__id2sid(evlist, e->id);
2212 if (!sid) {
2213 free(ev);
2214 return -ENOENT;
2215 }
2216
2217 e->idx = sid->idx;
2218 e->cpu = sid->cpu;
2219 e->tid = sid->tid;
2220 }
2221 }
2222
2223 sz = sizeof(struct id_index_event) + nr * sizeof(struct id_index_entry);
2224 ev->id_index.header.size = sz;
2225 ev->id_index.nr = nr;
2226
2227 err = process(tool, ev, NULL, machine);
2228out_err:
2229 free(ev);
2230
2231 return err;
2232}
2233