1 // SPDX-License-Identifier: GPL-2.0
2 #include <errno.h>
3 #include <signal.h>
4 #include <inttypes.h>
5 #include <linux/err.h>
6 #include <linux/kernel.h>
7 #include <linux/zalloc.h>
8 #include <api/fs/fs.h>
9
10 #include <byteswap.h>
11 #include <unistd.h>
12 #include <sys/types.h>
13 #include <sys/mman.h>
14 #include <perf/cpumap.h>
15
16 #include "map_symbol.h"
17 #include "branch.h"
18 #include "debug.h"
19 #include "env.h"
20 #include "evlist.h"
21 #include "evsel.h"
22 #include "memswap.h"
23 #include "map.h"
24 #include "symbol.h"
25 #include "session.h"
26 #include "tool.h"
27 #include "perf_regs.h"
28 #include "asm/bug.h"
29 #include "auxtrace.h"
30 #include "thread.h"
31 #include "thread-stack.h"
32 #include "sample-raw.h"
33 #include "stat.h"
34 #include "tsc.h"
35 #include "ui/progress.h"
36 #include "util.h"
37 #include "arch/common.h"
38 #include "units.h"
39 #include "annotate.h"
40 #include "perf.h"
41 #include <internal/lib.h>
42
43 static int perf_session__deliver_event(struct perf_session *session,
44 union perf_event *event,
45 const struct perf_tool *tool,
46 u64 file_offset,
47 const char *file_path);
48
perf_session__open(struct perf_session * session)49 static int perf_session__open(struct perf_session *session)
50 {
51 struct perf_data *data = session->data;
52
53 if (perf_session__read_header(session) < 0) {
54 pr_err("incompatible file format (rerun with -v to learn more)\n");
55 return -1;
56 }
57
58 if (perf_header__has_feat(&session->header, HEADER_AUXTRACE)) {
59 /* Auxiliary events may reference exited threads, hold onto dead ones. */
60 symbol_conf.keep_exited_threads = true;
61 }
62
63 if (perf_data__is_pipe(data))
64 return 0;
65
66 if (perf_header__has_feat(&session->header, HEADER_STAT))
67 return 0;
68
69 if (!evlist__valid_sample_type(session->evlist)) {
70 pr_err("non matching sample_type\n");
71 return -1;
72 }
73
74 if (!evlist__valid_sample_id_all(session->evlist)) {
75 pr_err("non matching sample_id_all\n");
76 return -1;
77 }
78
79 if (!evlist__valid_read_format(session->evlist)) {
80 pr_err("non matching read_format\n");
81 return -1;
82 }
83
84 return 0;
85 }
86
perf_session__set_id_hdr_size(struct perf_session * session)87 void perf_session__set_id_hdr_size(struct perf_session *session)
88 {
89 u16 id_hdr_size = evlist__id_hdr_size(session->evlist);
90
91 machines__set_id_hdr_size(&session->machines, id_hdr_size);
92 }
93
perf_session__create_kernel_maps(struct perf_session * session)94 int perf_session__create_kernel_maps(struct perf_session *session)
95 {
96 int ret = machine__create_kernel_maps(&session->machines.host);
97
98 if (ret >= 0)
99 ret = machines__create_guest_kernel_maps(&session->machines);
100 return ret;
101 }
102
perf_session__destroy_kernel_maps(struct perf_session * session)103 static void perf_session__destroy_kernel_maps(struct perf_session *session)
104 {
105 machines__destroy_kernel_maps(&session->machines);
106 }
107
perf_session__has_comm_exec(struct perf_session * session)108 static bool perf_session__has_comm_exec(struct perf_session *session)
109 {
110 struct evsel *evsel;
111
112 evlist__for_each_entry(session->evlist, evsel) {
113 if (evsel->core.attr.comm_exec)
114 return true;
115 }
116
117 return false;
118 }
119
perf_session__set_comm_exec(struct perf_session * session)120 static void perf_session__set_comm_exec(struct perf_session *session)
121 {
122 bool comm_exec = perf_session__has_comm_exec(session);
123
124 machines__set_comm_exec(&session->machines, comm_exec);
125 }
126
ordered_events__deliver_event(struct ordered_events * oe,struct ordered_event * event)127 static int ordered_events__deliver_event(struct ordered_events *oe,
128 struct ordered_event *event)
129 {
130 struct perf_session *session = container_of(oe, struct perf_session,
131 ordered_events);
132
133 return perf_session__deliver_event(session, event->event,
134 session->tool, event->file_offset,
135 event->file_path);
136 }
137
__perf_session__new(struct perf_data * data,struct perf_tool * tool,bool trace_event_repipe)138 struct perf_session *__perf_session__new(struct perf_data *data,
139 struct perf_tool *tool,
140 bool trace_event_repipe)
141 {
142 int ret = -ENOMEM;
143 struct perf_session *session = zalloc(sizeof(*session));
144
145 if (!session)
146 goto out;
147
148 session->trace_event_repipe = trace_event_repipe;
149 session->tool = tool;
150 session->decomp_data.zstd_decomp = &session->zstd_data;
151 session->active_decomp = &session->decomp_data;
152 INIT_LIST_HEAD(&session->auxtrace_index);
153 machines__init(&session->machines);
154 ordered_events__init(&session->ordered_events,
155 ordered_events__deliver_event, NULL);
156
157 perf_env__init(&session->header.env);
158 if (data) {
159 ret = perf_data__open(data);
160 if (ret < 0)
161 goto out_delete;
162
163 session->data = data;
164
165 if (perf_data__is_read(data)) {
166 ret = perf_session__open(session);
167 if (ret < 0)
168 goto out_delete;
169
170 /*
171 * set session attributes that are present in perf.data
172 * but not in pipe-mode.
173 */
174 if (!data->is_pipe) {
175 perf_session__set_id_hdr_size(session);
176 perf_session__set_comm_exec(session);
177 }
178
179 evlist__init_trace_event_sample_raw(session->evlist);
180
181 /* Open the directory data. */
182 if (data->is_dir) {
183 ret = perf_data__open_dir(data);
184 if (ret)
185 goto out_delete;
186 }
187
188 if (!symbol_conf.kallsyms_name &&
189 !symbol_conf.vmlinux_name)
190 symbol_conf.kallsyms_name = perf_data__kallsyms_name(data);
191 }
192 } else {
193 session->machines.host.env = &perf_env;
194 }
195
196 session->machines.host.single_address_space =
197 perf_env__single_address_space(session->machines.host.env);
198
199 if (!data || perf_data__is_write(data)) {
200 /*
201 * In O_RDONLY mode this will be performed when reading the
202 * kernel MMAP event, in perf_event__process_mmap().
203 */
204 if (perf_session__create_kernel_maps(session) < 0)
205 pr_warning("Cannot read kernel map\n");
206 }
207
208 /*
209 * In pipe-mode, evlist is empty until PERF_RECORD_HEADER_ATTR is
210 * processed, so evlist__sample_id_all is not meaningful here.
211 */
212 if ((!data || !data->is_pipe) && tool && tool->ordering_requires_timestamps &&
213 tool->ordered_events && !evlist__sample_id_all(session->evlist)) {
214 dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
215 tool->ordered_events = false;
216 }
217
218 return session;
219
220 out_delete:
221 perf_session__delete(session);
222 out:
223 return ERR_PTR(ret);
224 }
225
perf_decomp__release_events(struct decomp * next)226 static void perf_decomp__release_events(struct decomp *next)
227 {
228 struct decomp *decomp;
229 size_t mmap_len;
230
231 do {
232 decomp = next;
233 if (decomp == NULL)
234 break;
235 next = decomp->next;
236 mmap_len = decomp->mmap_len;
237 munmap(decomp, mmap_len);
238 } while (1);
239 }
240
perf_session__delete(struct perf_session * session)241 void perf_session__delete(struct perf_session *session)
242 {
243 if (session == NULL)
244 return;
245 auxtrace__free(session);
246 auxtrace_index__free(&session->auxtrace_index);
247 debuginfo_cache__delete();
248 perf_session__destroy_kernel_maps(session);
249 perf_decomp__release_events(session->decomp_data.decomp);
250 perf_env__exit(&session->header.env);
251 machines__exit(&session->machines);
252 if (session->data) {
253 if (perf_data__is_read(session->data))
254 evlist__delete(session->evlist);
255 perf_data__close(session->data);
256 }
257 #ifdef HAVE_LIBTRACEEVENT
258 trace_event__cleanup(&session->tevent);
259 #endif
260 free(session);
261 }
262
swap_sample_id_all(union perf_event * event,void * data)263 static void swap_sample_id_all(union perf_event *event, void *data)
264 {
265 void *end = (void *) event + event->header.size;
266 int size = end - data;
267
268 BUG_ON(size % sizeof(u64));
269 mem_bswap_64(data, size);
270 }
271
perf_event__all64_swap(union perf_event * event,bool sample_id_all __maybe_unused)272 static void perf_event__all64_swap(union perf_event *event,
273 bool sample_id_all __maybe_unused)
274 {
275 struct perf_event_header *hdr = &event->header;
276 mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr));
277 }
278
perf_event__comm_swap(union perf_event * event,bool sample_id_all)279 static void perf_event__comm_swap(union perf_event *event, bool sample_id_all)
280 {
281 event->comm.pid = bswap_32(event->comm.pid);
282 event->comm.tid = bswap_32(event->comm.tid);
283
284 if (sample_id_all) {
285 void *data = &event->comm.comm;
286
287 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64));
288 swap_sample_id_all(event, data);
289 }
290 }
291
perf_event__mmap_swap(union perf_event * event,bool sample_id_all)292 static void perf_event__mmap_swap(union perf_event *event,
293 bool sample_id_all)
294 {
295 event->mmap.pid = bswap_32(event->mmap.pid);
296 event->mmap.tid = bswap_32(event->mmap.tid);
297 event->mmap.start = bswap_64(event->mmap.start);
298 event->mmap.len = bswap_64(event->mmap.len);
299 event->mmap.pgoff = bswap_64(event->mmap.pgoff);
300
301 if (sample_id_all) {
302 void *data = &event->mmap.filename;
303
304 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64));
305 swap_sample_id_all(event, data);
306 }
307 }
308
perf_event__mmap2_swap(union perf_event * event,bool sample_id_all)309 static void perf_event__mmap2_swap(union perf_event *event,
310 bool sample_id_all)
311 {
312 event->mmap2.pid = bswap_32(event->mmap2.pid);
313 event->mmap2.tid = bswap_32(event->mmap2.tid);
314 event->mmap2.start = bswap_64(event->mmap2.start);
315 event->mmap2.len = bswap_64(event->mmap2.len);
316 event->mmap2.pgoff = bswap_64(event->mmap2.pgoff);
317
318 if (!(event->header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)) {
319 event->mmap2.maj = bswap_32(event->mmap2.maj);
320 event->mmap2.min = bswap_32(event->mmap2.min);
321 event->mmap2.ino = bswap_64(event->mmap2.ino);
322 event->mmap2.ino_generation = bswap_64(event->mmap2.ino_generation);
323 }
324
325 if (sample_id_all) {
326 void *data = &event->mmap2.filename;
327
328 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64));
329 swap_sample_id_all(event, data);
330 }
331 }
perf_event__task_swap(union perf_event * event,bool sample_id_all)332 static void perf_event__task_swap(union perf_event *event, bool sample_id_all)
333 {
334 event->fork.pid = bswap_32(event->fork.pid);
335 event->fork.tid = bswap_32(event->fork.tid);
336 event->fork.ppid = bswap_32(event->fork.ppid);
337 event->fork.ptid = bswap_32(event->fork.ptid);
338 event->fork.time = bswap_64(event->fork.time);
339
340 if (sample_id_all)
341 swap_sample_id_all(event, &event->fork + 1);
342 }
343
perf_event__read_swap(union perf_event * event,bool sample_id_all)344 static void perf_event__read_swap(union perf_event *event, bool sample_id_all)
345 {
346 event->read.pid = bswap_32(event->read.pid);
347 event->read.tid = bswap_32(event->read.tid);
348 event->read.value = bswap_64(event->read.value);
349 event->read.time_enabled = bswap_64(event->read.time_enabled);
350 event->read.time_running = bswap_64(event->read.time_running);
351 event->read.id = bswap_64(event->read.id);
352
353 if (sample_id_all)
354 swap_sample_id_all(event, &event->read + 1);
355 }
356
perf_event__aux_swap(union perf_event * event,bool sample_id_all)357 static void perf_event__aux_swap(union perf_event *event, bool sample_id_all)
358 {
359 event->aux.aux_offset = bswap_64(event->aux.aux_offset);
360 event->aux.aux_size = bswap_64(event->aux.aux_size);
361 event->aux.flags = bswap_64(event->aux.flags);
362
363 if (sample_id_all)
364 swap_sample_id_all(event, &event->aux + 1);
365 }
366
perf_event__itrace_start_swap(union perf_event * event,bool sample_id_all)367 static void perf_event__itrace_start_swap(union perf_event *event,
368 bool sample_id_all)
369 {
370 event->itrace_start.pid = bswap_32(event->itrace_start.pid);
371 event->itrace_start.tid = bswap_32(event->itrace_start.tid);
372
373 if (sample_id_all)
374 swap_sample_id_all(event, &event->itrace_start + 1);
375 }
376
perf_event__switch_swap(union perf_event * event,bool sample_id_all)377 static void perf_event__switch_swap(union perf_event *event, bool sample_id_all)
378 {
379 if (event->header.type == PERF_RECORD_SWITCH_CPU_WIDE) {
380 event->context_switch.next_prev_pid =
381 bswap_32(event->context_switch.next_prev_pid);
382 event->context_switch.next_prev_tid =
383 bswap_32(event->context_switch.next_prev_tid);
384 }
385
386 if (sample_id_all)
387 swap_sample_id_all(event, &event->context_switch + 1);
388 }
389
perf_event__text_poke_swap(union perf_event * event,bool sample_id_all)390 static void perf_event__text_poke_swap(union perf_event *event, bool sample_id_all)
391 {
392 event->text_poke.addr = bswap_64(event->text_poke.addr);
393 event->text_poke.old_len = bswap_16(event->text_poke.old_len);
394 event->text_poke.new_len = bswap_16(event->text_poke.new_len);
395
396 if (sample_id_all) {
397 size_t len = sizeof(event->text_poke.old_len) +
398 sizeof(event->text_poke.new_len) +
399 event->text_poke.old_len +
400 event->text_poke.new_len;
401 void *data = &event->text_poke.old_len;
402
403 data += PERF_ALIGN(len, sizeof(u64));
404 swap_sample_id_all(event, data);
405 }
406 }
407
perf_event__throttle_swap(union perf_event * event,bool sample_id_all)408 static void perf_event__throttle_swap(union perf_event *event,
409 bool sample_id_all)
410 {
411 event->throttle.time = bswap_64(event->throttle.time);
412 event->throttle.id = bswap_64(event->throttle.id);
413 event->throttle.stream_id = bswap_64(event->throttle.stream_id);
414
415 if (sample_id_all)
416 swap_sample_id_all(event, &event->throttle + 1);
417 }
418
perf_event__namespaces_swap(union perf_event * event,bool sample_id_all)419 static void perf_event__namespaces_swap(union perf_event *event,
420 bool sample_id_all)
421 {
422 u64 i;
423
424 event->namespaces.pid = bswap_32(event->namespaces.pid);
425 event->namespaces.tid = bswap_32(event->namespaces.tid);
426 event->namespaces.nr_namespaces = bswap_64(event->namespaces.nr_namespaces);
427
428 for (i = 0; i < event->namespaces.nr_namespaces; i++) {
429 struct perf_ns_link_info *ns = &event->namespaces.link_info[i];
430
431 ns->dev = bswap_64(ns->dev);
432 ns->ino = bswap_64(ns->ino);
433 }
434
435 if (sample_id_all)
436 swap_sample_id_all(event, &event->namespaces.link_info[i]);
437 }
438
perf_event__cgroup_swap(union perf_event * event,bool sample_id_all)439 static void perf_event__cgroup_swap(union perf_event *event, bool sample_id_all)
440 {
441 event->cgroup.id = bswap_64(event->cgroup.id);
442
443 if (sample_id_all) {
444 void *data = &event->cgroup.path;
445
446 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64));
447 swap_sample_id_all(event, data);
448 }
449 }
450
revbyte(u8 b)451 static u8 revbyte(u8 b)
452 {
453 int rev = (b >> 4) | ((b & 0xf) << 4);
454 rev = ((rev & 0xcc) >> 2) | ((rev & 0x33) << 2);
455 rev = ((rev & 0xaa) >> 1) | ((rev & 0x55) << 1);
456 return (u8) rev;
457 }
458
459 /*
460 * XXX this is hack in attempt to carry flags bitfield
461 * through endian village. ABI says:
462 *
463 * Bit-fields are allocated from right to left (least to most significant)
464 * on little-endian implementations and from left to right (most to least
465 * significant) on big-endian implementations.
466 *
467 * The above seems to be byte specific, so we need to reverse each
468 * byte of the bitfield. 'Internet' also says this might be implementation
469 * specific and we probably need proper fix and carry perf_event_attr
470 * bitfield flags in separate data file FEAT_ section. Thought this seems
471 * to work for now.
472 */
swap_bitfield(u8 * p,unsigned len)473 static void swap_bitfield(u8 *p, unsigned len)
474 {
475 unsigned i;
476
477 for (i = 0; i < len; i++) {
478 *p = revbyte(*p);
479 p++;
480 }
481 }
482
483 /* exported for swapping attributes in file header */
perf_event__attr_swap(struct perf_event_attr * attr)484 void perf_event__attr_swap(struct perf_event_attr *attr)
485 {
486 attr->type = bswap_32(attr->type);
487 attr->size = bswap_32(attr->size);
488
489 #define bswap_safe(f, n) \
490 (attr->size > (offsetof(struct perf_event_attr, f) + \
491 sizeof(attr->f) * (n)))
492 #define bswap_field(f, sz) \
493 do { \
494 if (bswap_safe(f, 0)) \
495 attr->f = bswap_##sz(attr->f); \
496 } while(0)
497 #define bswap_field_16(f) bswap_field(f, 16)
498 #define bswap_field_32(f) bswap_field(f, 32)
499 #define bswap_field_64(f) bswap_field(f, 64)
500
501 bswap_field_64(config);
502 bswap_field_64(sample_period);
503 bswap_field_64(sample_type);
504 bswap_field_64(read_format);
505 bswap_field_32(wakeup_events);
506 bswap_field_32(bp_type);
507 bswap_field_64(bp_addr);
508 bswap_field_64(bp_len);
509 bswap_field_64(branch_sample_type);
510 bswap_field_64(sample_regs_user);
511 bswap_field_32(sample_stack_user);
512 bswap_field_32(aux_watermark);
513 bswap_field_16(sample_max_stack);
514 bswap_field_32(aux_sample_size);
515
516 /*
517 * After read_format are bitfields. Check read_format because
518 * we are unable to use offsetof on bitfield.
519 */
520 if (bswap_safe(read_format, 1))
521 swap_bitfield((u8 *) (&attr->read_format + 1),
522 sizeof(u64));
523 #undef bswap_field_64
524 #undef bswap_field_32
525 #undef bswap_field
526 #undef bswap_safe
527 }
528
perf_event__hdr_attr_swap(union perf_event * event,bool sample_id_all __maybe_unused)529 static void perf_event__hdr_attr_swap(union perf_event *event,
530 bool sample_id_all __maybe_unused)
531 {
532 size_t size;
533
534 perf_event__attr_swap(&event->attr.attr);
535
536 size = event->header.size;
537 size -= perf_record_header_attr_id(event) - (void *)event;
538 mem_bswap_64(perf_record_header_attr_id(event), size);
539 }
540
perf_event__event_update_swap(union perf_event * event,bool sample_id_all __maybe_unused)541 static void perf_event__event_update_swap(union perf_event *event,
542 bool sample_id_all __maybe_unused)
543 {
544 event->event_update.type = bswap_64(event->event_update.type);
545 event->event_update.id = bswap_64(event->event_update.id);
546 }
547
perf_event__event_type_swap(union perf_event * event,bool sample_id_all __maybe_unused)548 static void perf_event__event_type_swap(union perf_event *event,
549 bool sample_id_all __maybe_unused)
550 {
551 event->event_type.event_type.event_id =
552 bswap_64(event->event_type.event_type.event_id);
553 }
554
perf_event__tracing_data_swap(union perf_event * event,bool sample_id_all __maybe_unused)555 static void perf_event__tracing_data_swap(union perf_event *event,
556 bool sample_id_all __maybe_unused)
557 {
558 event->tracing_data.size = bswap_32(event->tracing_data.size);
559 }
560
perf_event__auxtrace_info_swap(union perf_event * event,bool sample_id_all __maybe_unused)561 static void perf_event__auxtrace_info_swap(union perf_event *event,
562 bool sample_id_all __maybe_unused)
563 {
564 size_t size;
565
566 event->auxtrace_info.type = bswap_32(event->auxtrace_info.type);
567
568 size = event->header.size;
569 size -= (void *)&event->auxtrace_info.priv - (void *)event;
570 mem_bswap_64(event->auxtrace_info.priv, size);
571 }
572
perf_event__auxtrace_swap(union perf_event * event,bool sample_id_all __maybe_unused)573 static void perf_event__auxtrace_swap(union perf_event *event,
574 bool sample_id_all __maybe_unused)
575 {
576 event->auxtrace.size = bswap_64(event->auxtrace.size);
577 event->auxtrace.offset = bswap_64(event->auxtrace.offset);
578 event->auxtrace.reference = bswap_64(event->auxtrace.reference);
579 event->auxtrace.idx = bswap_32(event->auxtrace.idx);
580 event->auxtrace.tid = bswap_32(event->auxtrace.tid);
581 event->auxtrace.cpu = bswap_32(event->auxtrace.cpu);
582 }
583
perf_event__auxtrace_error_swap(union perf_event * event,bool sample_id_all __maybe_unused)584 static void perf_event__auxtrace_error_swap(union perf_event *event,
585 bool sample_id_all __maybe_unused)
586 {
587 event->auxtrace_error.type = bswap_32(event->auxtrace_error.type);
588 event->auxtrace_error.code = bswap_32(event->auxtrace_error.code);
589 event->auxtrace_error.cpu = bswap_32(event->auxtrace_error.cpu);
590 event->auxtrace_error.pid = bswap_32(event->auxtrace_error.pid);
591 event->auxtrace_error.tid = bswap_32(event->auxtrace_error.tid);
592 event->auxtrace_error.fmt = bswap_32(event->auxtrace_error.fmt);
593 event->auxtrace_error.ip = bswap_64(event->auxtrace_error.ip);
594 if (event->auxtrace_error.fmt)
595 event->auxtrace_error.time = bswap_64(event->auxtrace_error.time);
596 if (event->auxtrace_error.fmt >= 2) {
597 event->auxtrace_error.machine_pid = bswap_32(event->auxtrace_error.machine_pid);
598 event->auxtrace_error.vcpu = bswap_32(event->auxtrace_error.vcpu);
599 }
600 }
601
perf_event__thread_map_swap(union perf_event * event,bool sample_id_all __maybe_unused)602 static void perf_event__thread_map_swap(union perf_event *event,
603 bool sample_id_all __maybe_unused)
604 {
605 unsigned i;
606
607 event->thread_map.nr = bswap_64(event->thread_map.nr);
608
609 for (i = 0; i < event->thread_map.nr; i++)
610 event->thread_map.entries[i].pid = bswap_64(event->thread_map.entries[i].pid);
611 }
612
perf_event__cpu_map_swap(union perf_event * event,bool sample_id_all __maybe_unused)613 static void perf_event__cpu_map_swap(union perf_event *event,
614 bool sample_id_all __maybe_unused)
615 {
616 struct perf_record_cpu_map_data *data = &event->cpu_map.data;
617
618 data->type = bswap_16(data->type);
619
620 switch (data->type) {
621 case PERF_CPU_MAP__CPUS:
622 data->cpus_data.nr = bswap_16(data->cpus_data.nr);
623
624 for (unsigned i = 0; i < data->cpus_data.nr; i++)
625 data->cpus_data.cpu[i] = bswap_16(data->cpus_data.cpu[i]);
626 break;
627 case PERF_CPU_MAP__MASK:
628 data->mask32_data.long_size = bswap_16(data->mask32_data.long_size);
629
630 switch (data->mask32_data.long_size) {
631 case 4:
632 data->mask32_data.nr = bswap_16(data->mask32_data.nr);
633 for (unsigned i = 0; i < data->mask32_data.nr; i++)
634 data->mask32_data.mask[i] = bswap_32(data->mask32_data.mask[i]);
635 break;
636 case 8:
637 data->mask64_data.nr = bswap_16(data->mask64_data.nr);
638 for (unsigned i = 0; i < data->mask64_data.nr; i++)
639 data->mask64_data.mask[i] = bswap_64(data->mask64_data.mask[i]);
640 break;
641 default:
642 pr_err("cpu_map swap: unsupported long size\n");
643 }
644 break;
645 case PERF_CPU_MAP__RANGE_CPUS:
646 data->range_cpu_data.start_cpu = bswap_16(data->range_cpu_data.start_cpu);
647 data->range_cpu_data.end_cpu = bswap_16(data->range_cpu_data.end_cpu);
648 break;
649 default:
650 break;
651 }
652 }
653
perf_event__stat_config_swap(union perf_event * event,bool sample_id_all __maybe_unused)654 static void perf_event__stat_config_swap(union perf_event *event,
655 bool sample_id_all __maybe_unused)
656 {
657 u64 size;
658
659 size = bswap_64(event->stat_config.nr) * sizeof(event->stat_config.data[0]);
660 size += 1; /* nr item itself */
661 mem_bswap_64(&event->stat_config.nr, size);
662 }
663
perf_event__stat_swap(union perf_event * event,bool sample_id_all __maybe_unused)664 static void perf_event__stat_swap(union perf_event *event,
665 bool sample_id_all __maybe_unused)
666 {
667 event->stat.id = bswap_64(event->stat.id);
668 event->stat.thread = bswap_32(event->stat.thread);
669 event->stat.cpu = bswap_32(event->stat.cpu);
670 event->stat.val = bswap_64(event->stat.val);
671 event->stat.ena = bswap_64(event->stat.ena);
672 event->stat.run = bswap_64(event->stat.run);
673 }
674
perf_event__stat_round_swap(union perf_event * event,bool sample_id_all __maybe_unused)675 static void perf_event__stat_round_swap(union perf_event *event,
676 bool sample_id_all __maybe_unused)
677 {
678 event->stat_round.type = bswap_64(event->stat_round.type);
679 event->stat_round.time = bswap_64(event->stat_round.time);
680 }
681
perf_event__time_conv_swap(union perf_event * event,bool sample_id_all __maybe_unused)682 static void perf_event__time_conv_swap(union perf_event *event,
683 bool sample_id_all __maybe_unused)
684 {
685 event->time_conv.time_shift = bswap_64(event->time_conv.time_shift);
686 event->time_conv.time_mult = bswap_64(event->time_conv.time_mult);
687 event->time_conv.time_zero = bswap_64(event->time_conv.time_zero);
688
689 if (event_contains(event->time_conv, time_cycles)) {
690 event->time_conv.time_cycles = bswap_64(event->time_conv.time_cycles);
691 event->time_conv.time_mask = bswap_64(event->time_conv.time_mask);
692 }
693 }
694
695 typedef void (*perf_event__swap_op)(union perf_event *event,
696 bool sample_id_all);
697
698 static perf_event__swap_op perf_event__swap_ops[] = {
699 [PERF_RECORD_MMAP] = perf_event__mmap_swap,
700 [PERF_RECORD_MMAP2] = perf_event__mmap2_swap,
701 [PERF_RECORD_COMM] = perf_event__comm_swap,
702 [PERF_RECORD_FORK] = perf_event__task_swap,
703 [PERF_RECORD_EXIT] = perf_event__task_swap,
704 [PERF_RECORD_LOST] = perf_event__all64_swap,
705 [PERF_RECORD_READ] = perf_event__read_swap,
706 [PERF_RECORD_THROTTLE] = perf_event__throttle_swap,
707 [PERF_RECORD_UNTHROTTLE] = perf_event__throttle_swap,
708 [PERF_RECORD_SAMPLE] = perf_event__all64_swap,
709 [PERF_RECORD_AUX] = perf_event__aux_swap,
710 [PERF_RECORD_ITRACE_START] = perf_event__itrace_start_swap,
711 [PERF_RECORD_LOST_SAMPLES] = perf_event__all64_swap,
712 [PERF_RECORD_SWITCH] = perf_event__switch_swap,
713 [PERF_RECORD_SWITCH_CPU_WIDE] = perf_event__switch_swap,
714 [PERF_RECORD_NAMESPACES] = perf_event__namespaces_swap,
715 [PERF_RECORD_CGROUP] = perf_event__cgroup_swap,
716 [PERF_RECORD_TEXT_POKE] = perf_event__text_poke_swap,
717 [PERF_RECORD_AUX_OUTPUT_HW_ID] = perf_event__all64_swap,
718 [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap,
719 [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap,
720 [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
721 [PERF_RECORD_HEADER_BUILD_ID] = NULL,
722 [PERF_RECORD_ID_INDEX] = perf_event__all64_swap,
723 [PERF_RECORD_AUXTRACE_INFO] = perf_event__auxtrace_info_swap,
724 [PERF_RECORD_AUXTRACE] = perf_event__auxtrace_swap,
725 [PERF_RECORD_AUXTRACE_ERROR] = perf_event__auxtrace_error_swap,
726 [PERF_RECORD_THREAD_MAP] = perf_event__thread_map_swap,
727 [PERF_RECORD_CPU_MAP] = perf_event__cpu_map_swap,
728 [PERF_RECORD_STAT_CONFIG] = perf_event__stat_config_swap,
729 [PERF_RECORD_STAT] = perf_event__stat_swap,
730 [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap,
731 [PERF_RECORD_EVENT_UPDATE] = perf_event__event_update_swap,
732 [PERF_RECORD_TIME_CONV] = perf_event__time_conv_swap,
733 [PERF_RECORD_HEADER_MAX] = NULL,
734 };
735
736 /*
737 * When perf record finishes a pass on every buffers, it records this pseudo
738 * event.
739 * We record the max timestamp t found in the pass n.
740 * Assuming these timestamps are monotonic across cpus, we know that if
741 * a buffer still has events with timestamps below t, they will be all
742 * available and then read in the pass n + 1.
743 * Hence when we start to read the pass n + 2, we can safely flush every
744 * events with timestamps below t.
745 *
746 * ============ PASS n =================
747 * CPU 0 | CPU 1
748 * |
749 * cnt1 timestamps | cnt2 timestamps
750 * 1 | 2
751 * 2 | 3
752 * - | 4 <--- max recorded
753 *
754 * ============ PASS n + 1 ==============
755 * CPU 0 | CPU 1
756 * |
757 * cnt1 timestamps | cnt2 timestamps
758 * 3 | 5
759 * 4 | 6
760 * 5 | 7 <---- max recorded
761 *
762 * Flush every events below timestamp 4
763 *
764 * ============ PASS n + 2 ==============
765 * CPU 0 | CPU 1
766 * |
767 * cnt1 timestamps | cnt2 timestamps
768 * 6 | 8
769 * 7 | 9
770 * - | 10
771 *
772 * Flush every events below timestamp 7
773 * etc...
774 */
perf_event__process_finished_round(const struct perf_tool * tool __maybe_unused,union perf_event * event __maybe_unused,struct ordered_events * oe)775 int perf_event__process_finished_round(const struct perf_tool *tool __maybe_unused,
776 union perf_event *event __maybe_unused,
777 struct ordered_events *oe)
778 {
779 if (dump_trace)
780 fprintf(stdout, "\n");
781 return ordered_events__flush(oe, OE_FLUSH__ROUND);
782 }
783
perf_session__queue_event(struct perf_session * s,union perf_event * event,u64 timestamp,u64 file_offset,const char * file_path)784 int perf_session__queue_event(struct perf_session *s, union perf_event *event,
785 u64 timestamp, u64 file_offset, const char *file_path)
786 {
787 return ordered_events__queue(&s->ordered_events, event, timestamp, file_offset, file_path);
788 }
789
callchain__lbr_callstack_printf(struct perf_sample * sample)790 static void callchain__lbr_callstack_printf(struct perf_sample *sample)
791 {
792 struct ip_callchain *callchain = sample->callchain;
793 struct branch_stack *lbr_stack = sample->branch_stack;
794 struct branch_entry *entries = perf_sample__branch_entries(sample);
795 u64 kernel_callchain_nr = callchain->nr;
796 unsigned int i;
797
798 for (i = 0; i < kernel_callchain_nr; i++) {
799 if (callchain->ips[i] == PERF_CONTEXT_USER)
800 break;
801 }
802
803 if ((i != kernel_callchain_nr) && lbr_stack->nr) {
804 u64 total_nr;
805 /*
806 * LBR callstack can only get user call chain,
807 * i is kernel call chain number,
808 * 1 is PERF_CONTEXT_USER.
809 *
810 * The user call chain is stored in LBR registers.
811 * LBR are pair registers. The caller is stored
812 * in "from" register, while the callee is stored
813 * in "to" register.
814 * For example, there is a call stack
815 * "A"->"B"->"C"->"D".
816 * The LBR registers will be recorded like
817 * "C"->"D", "B"->"C", "A"->"B".
818 * So only the first "to" register and all "from"
819 * registers are needed to construct the whole stack.
820 */
821 total_nr = i + 1 + lbr_stack->nr + 1;
822 kernel_callchain_nr = i + 1;
823
824 printf("... LBR call chain: nr:%" PRIu64 "\n", total_nr);
825
826 for (i = 0; i < kernel_callchain_nr; i++)
827 printf("..... %2d: %016" PRIx64 "\n",
828 i, callchain->ips[i]);
829
830 printf("..... %2d: %016" PRIx64 "\n",
831 (int)(kernel_callchain_nr), entries[0].to);
832 for (i = 0; i < lbr_stack->nr; i++)
833 printf("..... %2d: %016" PRIx64 "\n",
834 (int)(i + kernel_callchain_nr + 1), entries[i].from);
835 }
836 }
837
callchain__printf(struct evsel * evsel,struct perf_sample * sample)838 static void callchain__printf(struct evsel *evsel,
839 struct perf_sample *sample)
840 {
841 unsigned int i;
842 struct ip_callchain *callchain = sample->callchain;
843
844 if (evsel__has_branch_callstack(evsel))
845 callchain__lbr_callstack_printf(sample);
846
847 printf("... FP chain: nr:%" PRIu64 "\n", callchain->nr);
848
849 for (i = 0; i < callchain->nr; i++)
850 printf("..... %2d: %016" PRIx64 "\n",
851 i, callchain->ips[i]);
852 }
853
branch_stack__printf(struct perf_sample * sample,struct evsel * evsel)854 static void branch_stack__printf(struct perf_sample *sample,
855 struct evsel *evsel)
856 {
857 struct branch_entry *entries = perf_sample__branch_entries(sample);
858 bool callstack = evsel__has_branch_callstack(evsel);
859 u64 *branch_stack_cntr = sample->branch_stack_cntr;
860 uint64_t i;
861
862 if (!callstack) {
863 printf("%s: nr:%" PRIu64 "\n", "... branch stack", sample->branch_stack->nr);
864 } else {
865 /* the reason of adding 1 to nr is because after expanding
866 * branch stack it generates nr + 1 callstack records. e.g.,
867 * B()->C()
868 * A()->B()
869 * the final callstack should be:
870 * C()
871 * B()
872 * A()
873 */
874 printf("%s: nr:%" PRIu64 "\n", "... branch callstack", sample->branch_stack->nr+1);
875 }
876
877 for (i = 0; i < sample->branch_stack->nr; i++) {
878 struct branch_entry *e = &entries[i];
879
880 if (!callstack) {
881 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 " %hu cycles %s%s%s%s %x %s %s\n",
882 i, e->from, e->to,
883 (unsigned short)e->flags.cycles,
884 e->flags.mispred ? "M" : " ",
885 e->flags.predicted ? "P" : " ",
886 e->flags.abort ? "A" : " ",
887 e->flags.in_tx ? "T" : " ",
888 (unsigned)e->flags.reserved,
889 get_branch_type(e),
890 e->flags.spec ? branch_spec_desc(e->flags.spec) : "");
891 } else {
892 if (i == 0) {
893 printf("..... %2"PRIu64": %016" PRIx64 "\n"
894 "..... %2"PRIu64": %016" PRIx64 "\n",
895 i, e->to, i+1, e->from);
896 } else {
897 printf("..... %2"PRIu64": %016" PRIx64 "\n", i+1, e->from);
898 }
899 }
900 }
901
902 if (branch_stack_cntr) {
903 unsigned int br_cntr_width, br_cntr_nr;
904
905 perf_env__find_br_cntr_info(evsel__env(evsel), &br_cntr_nr, &br_cntr_width);
906 printf("... branch stack counters: nr:%" PRIu64 " (counter width: %u max counter nr:%u)\n",
907 sample->branch_stack->nr, br_cntr_width, br_cntr_nr);
908 for (i = 0; i < sample->branch_stack->nr; i++)
909 printf("..... %2"PRIu64": %016" PRIx64 "\n", i, branch_stack_cntr[i]);
910 }
911 }
912
regs_dump__printf(u64 mask,u64 * regs,const char * arch)913 static void regs_dump__printf(u64 mask, u64 *regs, const char *arch)
914 {
915 unsigned rid, i = 0;
916
917 for_each_set_bit(rid, (unsigned long *) &mask, sizeof(mask) * 8) {
918 u64 val = regs[i++];
919
920 printf(".... %-5s 0x%016" PRIx64 "\n",
921 perf_reg_name(rid, arch), val);
922 }
923 }
924
925 static const char *regs_abi[] = {
926 [PERF_SAMPLE_REGS_ABI_NONE] = "none",
927 [PERF_SAMPLE_REGS_ABI_32] = "32-bit",
928 [PERF_SAMPLE_REGS_ABI_64] = "64-bit",
929 };
930
regs_dump_abi(struct regs_dump * d)931 static inline const char *regs_dump_abi(struct regs_dump *d)
932 {
933 if (d->abi > PERF_SAMPLE_REGS_ABI_64)
934 return "unknown";
935
936 return regs_abi[d->abi];
937 }
938
regs__printf(const char * type,struct regs_dump * regs,const char * arch)939 static void regs__printf(const char *type, struct regs_dump *regs, const char *arch)
940 {
941 u64 mask = regs->mask;
942
943 printf("... %s regs: mask 0x%" PRIx64 " ABI %s\n",
944 type,
945 mask,
946 regs_dump_abi(regs));
947
948 regs_dump__printf(mask, regs->regs, arch);
949 }
950
regs_user__printf(struct perf_sample * sample,const char * arch)951 static void regs_user__printf(struct perf_sample *sample, const char *arch)
952 {
953 struct regs_dump *user_regs = &sample->user_regs;
954
955 if (user_regs->regs)
956 regs__printf("user", user_regs, arch);
957 }
958
regs_intr__printf(struct perf_sample * sample,const char * arch)959 static void regs_intr__printf(struct perf_sample *sample, const char *arch)
960 {
961 struct regs_dump *intr_regs = &sample->intr_regs;
962
963 if (intr_regs->regs)
964 regs__printf("intr", intr_regs, arch);
965 }
966
stack_user__printf(struct stack_dump * dump)967 static void stack_user__printf(struct stack_dump *dump)
968 {
969 printf("... ustack: size %" PRIu64 ", offset 0x%x\n",
970 dump->size, dump->offset);
971 }
972
evlist__print_tstamp(struct evlist * evlist,union perf_event * event,struct perf_sample * sample)973 static void evlist__print_tstamp(struct evlist *evlist, union perf_event *event, struct perf_sample *sample)
974 {
975 u64 sample_type = __evlist__combined_sample_type(evlist);
976
977 if (event->header.type != PERF_RECORD_SAMPLE &&
978 !evlist__sample_id_all(evlist)) {
979 fputs("-1 -1 ", stdout);
980 return;
981 }
982
983 if ((sample_type & PERF_SAMPLE_CPU))
984 printf("%u ", sample->cpu);
985
986 if (sample_type & PERF_SAMPLE_TIME)
987 printf("%" PRIu64 " ", sample->time);
988 }
989
sample_read__printf(struct perf_sample * sample,u64 read_format)990 static void sample_read__printf(struct perf_sample *sample, u64 read_format)
991 {
992 printf("... sample_read:\n");
993
994 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
995 printf("...... time enabled %016" PRIx64 "\n",
996 sample->read.time_enabled);
997
998 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
999 printf("...... time running %016" PRIx64 "\n",
1000 sample->read.time_running);
1001
1002 if (read_format & PERF_FORMAT_GROUP) {
1003 struct sample_read_value *value = sample->read.group.values;
1004
1005 printf(".... group nr %" PRIu64 "\n", sample->read.group.nr);
1006
1007 sample_read_group__for_each(value, sample->read.group.nr, read_format) {
1008 printf("..... id %016" PRIx64
1009 ", value %016" PRIx64,
1010 value->id, value->value);
1011 if (read_format & PERF_FORMAT_LOST)
1012 printf(", lost %" PRIu64, value->lost);
1013 printf("\n");
1014 }
1015 } else {
1016 printf("..... id %016" PRIx64 ", value %016" PRIx64,
1017 sample->read.one.id, sample->read.one.value);
1018 if (read_format & PERF_FORMAT_LOST)
1019 printf(", lost %" PRIu64, sample->read.one.lost);
1020 printf("\n");
1021 }
1022 }
1023
dump_event(struct evlist * evlist,union perf_event * event,u64 file_offset,struct perf_sample * sample,const char * file_path)1024 static void dump_event(struct evlist *evlist, union perf_event *event,
1025 u64 file_offset, struct perf_sample *sample,
1026 const char *file_path)
1027 {
1028 if (!dump_trace)
1029 return;
1030
1031 printf("\n%#" PRIx64 "@%s [%#x]: event: %d\n",
1032 file_offset, file_path, event->header.size, event->header.type);
1033
1034 trace_event(event);
1035 if (event->header.type == PERF_RECORD_SAMPLE && evlist->trace_event_sample_raw)
1036 evlist->trace_event_sample_raw(evlist, event, sample);
1037
1038 if (sample)
1039 evlist__print_tstamp(evlist, event, sample);
1040
1041 printf("%#" PRIx64 " [%#x]: PERF_RECORD_%s", file_offset,
1042 event->header.size, perf_event__name(event->header.type));
1043 }
1044
get_page_size_name(u64 size,char * str)1045 char *get_page_size_name(u64 size, char *str)
1046 {
1047 if (!size || !unit_number__scnprintf(str, PAGE_SIZE_NAME_LEN, size))
1048 snprintf(str, PAGE_SIZE_NAME_LEN, "%s", "N/A");
1049
1050 return str;
1051 }
1052
dump_sample(struct evsel * evsel,union perf_event * event,struct perf_sample * sample,const char * arch)1053 static void dump_sample(struct evsel *evsel, union perf_event *event,
1054 struct perf_sample *sample, const char *arch)
1055 {
1056 u64 sample_type;
1057 char str[PAGE_SIZE_NAME_LEN];
1058
1059 if (!dump_trace)
1060 return;
1061
1062 printf("(IP, 0x%x): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n",
1063 event->header.misc, sample->pid, sample->tid, sample->ip,
1064 sample->period, sample->addr);
1065
1066 sample_type = evsel->core.attr.sample_type;
1067
1068 if (evsel__has_callchain(evsel))
1069 callchain__printf(evsel, sample);
1070
1071 if (evsel__has_br_stack(evsel))
1072 branch_stack__printf(sample, evsel);
1073
1074 if (sample_type & PERF_SAMPLE_REGS_USER)
1075 regs_user__printf(sample, arch);
1076
1077 if (sample_type & PERF_SAMPLE_REGS_INTR)
1078 regs_intr__printf(sample, arch);
1079
1080 if (sample_type & PERF_SAMPLE_STACK_USER)
1081 stack_user__printf(&sample->user_stack);
1082
1083 if (sample_type & PERF_SAMPLE_WEIGHT_TYPE) {
1084 printf("... weight: %" PRIu64 "", sample->weight);
1085 if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT) {
1086 printf(",0x%"PRIx16"", sample->ins_lat);
1087 printf(",0x%"PRIx16"", sample->p_stage_cyc);
1088 }
1089 printf("\n");
1090 }
1091
1092 if (sample_type & PERF_SAMPLE_DATA_SRC)
1093 printf(" . data_src: 0x%"PRIx64"\n", sample->data_src);
1094
1095 if (sample_type & PERF_SAMPLE_PHYS_ADDR)
1096 printf(" .. phys_addr: 0x%"PRIx64"\n", sample->phys_addr);
1097
1098 if (sample_type & PERF_SAMPLE_DATA_PAGE_SIZE)
1099 printf(" .. data page size: %s\n", get_page_size_name(sample->data_page_size, str));
1100
1101 if (sample_type & PERF_SAMPLE_CODE_PAGE_SIZE)
1102 printf(" .. code page size: %s\n", get_page_size_name(sample->code_page_size, str));
1103
1104 if (sample_type & PERF_SAMPLE_TRANSACTION)
1105 printf("... transaction: %" PRIx64 "\n", sample->transaction);
1106
1107 if (sample_type & PERF_SAMPLE_READ)
1108 sample_read__printf(sample, evsel->core.attr.read_format);
1109 }
1110
dump_read(struct evsel * evsel,union perf_event * event)1111 static void dump_read(struct evsel *evsel, union perf_event *event)
1112 {
1113 struct perf_record_read *read_event = &event->read;
1114 u64 read_format;
1115
1116 if (!dump_trace)
1117 return;
1118
1119 printf(": %d %d %s %" PRI_lu64 "\n", event->read.pid, event->read.tid,
1120 evsel__name(evsel), event->read.value);
1121
1122 if (!evsel)
1123 return;
1124
1125 read_format = evsel->core.attr.read_format;
1126
1127 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1128 printf("... time enabled : %" PRI_lu64 "\n", read_event->time_enabled);
1129
1130 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
1131 printf("... time running : %" PRI_lu64 "\n", read_event->time_running);
1132
1133 if (read_format & PERF_FORMAT_ID)
1134 printf("... id : %" PRI_lu64 "\n", read_event->id);
1135
1136 if (read_format & PERF_FORMAT_LOST)
1137 printf("... lost : %" PRI_lu64 "\n", read_event->lost);
1138 }
1139
machines__find_for_cpumode(struct machines * machines,union perf_event * event,struct perf_sample * sample)1140 static struct machine *machines__find_for_cpumode(struct machines *machines,
1141 union perf_event *event,
1142 struct perf_sample *sample)
1143 {
1144 if (perf_guest &&
1145 ((sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL) ||
1146 (sample->cpumode == PERF_RECORD_MISC_GUEST_USER))) {
1147 u32 pid;
1148
1149 if (sample->machine_pid)
1150 pid = sample->machine_pid;
1151 else if (event->header.type == PERF_RECORD_MMAP
1152 || event->header.type == PERF_RECORD_MMAP2)
1153 pid = event->mmap.pid;
1154 else
1155 pid = sample->pid;
1156
1157 /*
1158 * Guest code machine is created as needed and does not use
1159 * DEFAULT_GUEST_KERNEL_ID.
1160 */
1161 if (symbol_conf.guest_code)
1162 return machines__findnew(machines, pid);
1163
1164 return machines__find_guest(machines, pid);
1165 }
1166
1167 return &machines->host;
1168 }
1169
deliver_sample_value(struct evlist * evlist,const struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct sample_read_value * v,struct machine * machine,bool per_thread)1170 static int deliver_sample_value(struct evlist *evlist,
1171 const struct perf_tool *tool,
1172 union perf_event *event,
1173 struct perf_sample *sample,
1174 struct sample_read_value *v,
1175 struct machine *machine,
1176 bool per_thread)
1177 {
1178 struct perf_sample_id *sid = evlist__id2sid(evlist, v->id);
1179 struct evsel *evsel;
1180 u64 *storage = NULL;
1181
1182 if (sid) {
1183 storage = perf_sample_id__get_period_storage(sid, sample->tid, per_thread);
1184 }
1185
1186 if (storage) {
1187 sample->id = v->id;
1188 sample->period = v->value - *storage;
1189 *storage = v->value;
1190 }
1191
1192 if (!storage || sid->evsel == NULL) {
1193 ++evlist->stats.nr_unknown_id;
1194 return 0;
1195 }
1196
1197 /*
1198 * There's no reason to deliver sample
1199 * for zero period, bail out.
1200 */
1201 if (!sample->period)
1202 return 0;
1203
1204 evsel = container_of(sid->evsel, struct evsel, core);
1205 return tool->sample(tool, event, sample, evsel, machine);
1206 }
1207
deliver_sample_group(struct evlist * evlist,const struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct machine * machine,u64 read_format,bool per_thread)1208 static int deliver_sample_group(struct evlist *evlist,
1209 const struct perf_tool *tool,
1210 union perf_event *event,
1211 struct perf_sample *sample,
1212 struct machine *machine,
1213 u64 read_format,
1214 bool per_thread)
1215 {
1216 int ret = -EINVAL;
1217 struct sample_read_value *v = sample->read.group.values;
1218
1219 if (tool->dont_split_sample_group)
1220 return deliver_sample_value(evlist, tool, event, sample, v, machine,
1221 per_thread);
1222
1223 sample_read_group__for_each(v, sample->read.group.nr, read_format) {
1224 ret = deliver_sample_value(evlist, tool, event, sample, v,
1225 machine, per_thread);
1226 if (ret)
1227 break;
1228 }
1229
1230 return ret;
1231 }
1232
evlist__deliver_sample(struct evlist * evlist,const struct perf_tool * tool,union perf_event * event,struct perf_sample * sample,struct evsel * evsel,struct machine * machine)1233 static int evlist__deliver_sample(struct evlist *evlist, const struct perf_tool *tool,
1234 union perf_event *event, struct perf_sample *sample,
1235 struct evsel *evsel, struct machine *machine)
1236 {
1237 /* We know evsel != NULL. */
1238 u64 sample_type = evsel->core.attr.sample_type;
1239 u64 read_format = evsel->core.attr.read_format;
1240 bool per_thread = perf_evsel__attr_has_per_thread_sample_period(&evsel->core);
1241
1242 /* Standard sample delivery. */
1243 if (!(sample_type & PERF_SAMPLE_READ))
1244 return tool->sample(tool, event, sample, evsel, machine);
1245
1246 /* For PERF_SAMPLE_READ we have either single or group mode. */
1247 if (read_format & PERF_FORMAT_GROUP)
1248 return deliver_sample_group(evlist, tool, event, sample,
1249 machine, read_format, per_thread);
1250 else
1251 return deliver_sample_value(evlist, tool, event, sample,
1252 &sample->read.one, machine,
1253 per_thread);
1254 }
1255
machines__deliver_event(struct machines * machines,struct evlist * evlist,union perf_event * event,struct perf_sample * sample,const struct perf_tool * tool,u64 file_offset,const char * file_path)1256 static int machines__deliver_event(struct machines *machines,
1257 struct evlist *evlist,
1258 union perf_event *event,
1259 struct perf_sample *sample,
1260 const struct perf_tool *tool, u64 file_offset,
1261 const char *file_path)
1262 {
1263 struct evsel *evsel;
1264 struct machine *machine;
1265
1266 dump_event(evlist, event, file_offset, sample, file_path);
1267
1268 evsel = evlist__id2evsel(evlist, sample->id);
1269
1270 machine = machines__find_for_cpumode(machines, event, sample);
1271
1272 switch (event->header.type) {
1273 case PERF_RECORD_SAMPLE:
1274 if (evsel == NULL) {
1275 ++evlist->stats.nr_unknown_id;
1276 return 0;
1277 }
1278 if (machine == NULL) {
1279 ++evlist->stats.nr_unprocessable_samples;
1280 dump_sample(evsel, event, sample, perf_env__arch(NULL));
1281 return 0;
1282 }
1283 dump_sample(evsel, event, sample, perf_env__arch(machine->env));
1284 return evlist__deliver_sample(evlist, tool, event, sample, evsel, machine);
1285 case PERF_RECORD_MMAP:
1286 return tool->mmap(tool, event, sample, machine);
1287 case PERF_RECORD_MMAP2:
1288 if (event->header.misc & PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT)
1289 ++evlist->stats.nr_proc_map_timeout;
1290 return tool->mmap2(tool, event, sample, machine);
1291 case PERF_RECORD_COMM:
1292 return tool->comm(tool, event, sample, machine);
1293 case PERF_RECORD_NAMESPACES:
1294 return tool->namespaces(tool, event, sample, machine);
1295 case PERF_RECORD_CGROUP:
1296 return tool->cgroup(tool, event, sample, machine);
1297 case PERF_RECORD_FORK:
1298 return tool->fork(tool, event, sample, machine);
1299 case PERF_RECORD_EXIT:
1300 return tool->exit(tool, event, sample, machine);
1301 case PERF_RECORD_LOST:
1302 if (tool->lost == perf_event__process_lost)
1303 evlist->stats.total_lost += event->lost.lost;
1304 return tool->lost(tool, event, sample, machine);
1305 case PERF_RECORD_LOST_SAMPLES:
1306 if (event->header.misc & PERF_RECORD_MISC_LOST_SAMPLES_BPF)
1307 evlist->stats.total_dropped_samples += event->lost_samples.lost;
1308 else if (tool->lost_samples == perf_event__process_lost_samples)
1309 evlist->stats.total_lost_samples += event->lost_samples.lost;
1310 return tool->lost_samples(tool, event, sample, machine);
1311 case PERF_RECORD_READ:
1312 dump_read(evsel, event);
1313 return tool->read(tool, event, sample, evsel, machine);
1314 case PERF_RECORD_THROTTLE:
1315 return tool->throttle(tool, event, sample, machine);
1316 case PERF_RECORD_UNTHROTTLE:
1317 return tool->unthrottle(tool, event, sample, machine);
1318 case PERF_RECORD_AUX:
1319 if (tool->aux == perf_event__process_aux) {
1320 if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
1321 evlist->stats.total_aux_lost += 1;
1322 if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
1323 evlist->stats.total_aux_partial += 1;
1324 if (event->aux.flags & PERF_AUX_FLAG_COLLISION)
1325 evlist->stats.total_aux_collision += 1;
1326 }
1327 return tool->aux(tool, event, sample, machine);
1328 case PERF_RECORD_ITRACE_START:
1329 return tool->itrace_start(tool, event, sample, machine);
1330 case PERF_RECORD_SWITCH:
1331 case PERF_RECORD_SWITCH_CPU_WIDE:
1332 return tool->context_switch(tool, event, sample, machine);
1333 case PERF_RECORD_KSYMBOL:
1334 return tool->ksymbol(tool, event, sample, machine);
1335 case PERF_RECORD_BPF_EVENT:
1336 return tool->bpf(tool, event, sample, machine);
1337 case PERF_RECORD_TEXT_POKE:
1338 return tool->text_poke(tool, event, sample, machine);
1339 case PERF_RECORD_AUX_OUTPUT_HW_ID:
1340 return tool->aux_output_hw_id(tool, event, sample, machine);
1341 default:
1342 ++evlist->stats.nr_unknown_events;
1343 return -1;
1344 }
1345 }
1346
perf_session__deliver_event(struct perf_session * session,union perf_event * event,const struct perf_tool * tool,u64 file_offset,const char * file_path)1347 static int perf_session__deliver_event(struct perf_session *session,
1348 union perf_event *event,
1349 const struct perf_tool *tool,
1350 u64 file_offset,
1351 const char *file_path)
1352 {
1353 struct perf_sample sample;
1354 int ret = evlist__parse_sample(session->evlist, event, &sample);
1355
1356 if (ret) {
1357 pr_err("Can't parse sample, err = %d\n", ret);
1358 return ret;
1359 }
1360
1361 ret = auxtrace__process_event(session, event, &sample, tool);
1362 if (ret < 0)
1363 return ret;
1364 if (ret > 0)
1365 return 0;
1366
1367 ret = machines__deliver_event(&session->machines, session->evlist,
1368 event, &sample, tool, file_offset, file_path);
1369
1370 if (dump_trace && sample.aux_sample.size)
1371 auxtrace__dump_auxtrace_sample(session, &sample);
1372
1373 return ret;
1374 }
1375
perf_session__process_user_event(struct perf_session * session,union perf_event * event,u64 file_offset,const char * file_path)1376 static s64 perf_session__process_user_event(struct perf_session *session,
1377 union perf_event *event,
1378 u64 file_offset,
1379 const char *file_path)
1380 {
1381 struct ordered_events *oe = &session->ordered_events;
1382 const struct perf_tool *tool = session->tool;
1383 struct perf_sample sample = { .time = 0, };
1384 int fd = perf_data__fd(session->data);
1385 int err;
1386
1387 if (event->header.type != PERF_RECORD_COMPRESSED || perf_tool__compressed_is_stub(tool))
1388 dump_event(session->evlist, event, file_offset, &sample, file_path);
1389
1390 /* These events are processed right away */
1391 switch (event->header.type) {
1392 case PERF_RECORD_HEADER_ATTR:
1393 err = tool->attr(tool, event, &session->evlist);
1394 if (err == 0) {
1395 perf_session__set_id_hdr_size(session);
1396 perf_session__set_comm_exec(session);
1397 }
1398 return err;
1399 case PERF_RECORD_EVENT_UPDATE:
1400 return tool->event_update(tool, event, &session->evlist);
1401 case PERF_RECORD_HEADER_EVENT_TYPE:
1402 /*
1403 * Deprecated, but we need to handle it for sake
1404 * of old data files create in pipe mode.
1405 */
1406 return 0;
1407 case PERF_RECORD_HEADER_TRACING_DATA:
1408 /*
1409 * Setup for reading amidst mmap, but only when we
1410 * are in 'file' mode. The 'pipe' fd is in proper
1411 * place already.
1412 */
1413 if (!perf_data__is_pipe(session->data))
1414 lseek(fd, file_offset, SEEK_SET);
1415 return tool->tracing_data(session, event);
1416 case PERF_RECORD_HEADER_BUILD_ID:
1417 return tool->build_id(session, event);
1418 case PERF_RECORD_FINISHED_ROUND:
1419 return tool->finished_round(tool, event, oe);
1420 case PERF_RECORD_ID_INDEX:
1421 return tool->id_index(session, event);
1422 case PERF_RECORD_AUXTRACE_INFO:
1423 return tool->auxtrace_info(session, event);
1424 case PERF_RECORD_AUXTRACE:
1425 /*
1426 * Setup for reading amidst mmap, but only when we
1427 * are in 'file' mode. The 'pipe' fd is in proper
1428 * place already.
1429 */
1430 if (!perf_data__is_pipe(session->data))
1431 lseek(fd, file_offset + event->header.size, SEEK_SET);
1432 return tool->auxtrace(session, event);
1433 case PERF_RECORD_AUXTRACE_ERROR:
1434 perf_session__auxtrace_error_inc(session, event);
1435 return tool->auxtrace_error(session, event);
1436 case PERF_RECORD_THREAD_MAP:
1437 return tool->thread_map(session, event);
1438 case PERF_RECORD_CPU_MAP:
1439 return tool->cpu_map(session, event);
1440 case PERF_RECORD_STAT_CONFIG:
1441 return tool->stat_config(session, event);
1442 case PERF_RECORD_STAT:
1443 return tool->stat(session, event);
1444 case PERF_RECORD_STAT_ROUND:
1445 return tool->stat_round(session, event);
1446 case PERF_RECORD_TIME_CONV:
1447 session->time_conv = event->time_conv;
1448 return tool->time_conv(session, event);
1449 case PERF_RECORD_HEADER_FEATURE:
1450 return tool->feature(session, event);
1451 case PERF_RECORD_COMPRESSED:
1452 err = tool->compressed(session, event, file_offset, file_path);
1453 if (err)
1454 dump_event(session->evlist, event, file_offset, &sample, file_path);
1455 return err;
1456 case PERF_RECORD_FINISHED_INIT:
1457 return tool->finished_init(session, event);
1458 default:
1459 return -EINVAL;
1460 }
1461 }
1462
perf_session__deliver_synth_event(struct perf_session * session,union perf_event * event,struct perf_sample * sample)1463 int perf_session__deliver_synth_event(struct perf_session *session,
1464 union perf_event *event,
1465 struct perf_sample *sample)
1466 {
1467 struct evlist *evlist = session->evlist;
1468 const struct perf_tool *tool = session->tool;
1469
1470 events_stats__inc(&evlist->stats, event->header.type);
1471
1472 if (event->header.type >= PERF_RECORD_USER_TYPE_START)
1473 return perf_session__process_user_event(session, event, 0, NULL);
1474
1475 return machines__deliver_event(&session->machines, evlist, event, sample, tool, 0, NULL);
1476 }
1477
perf_session__deliver_synth_attr_event(struct perf_session * session,const struct perf_event_attr * attr,u64 id)1478 int perf_session__deliver_synth_attr_event(struct perf_session *session,
1479 const struct perf_event_attr *attr,
1480 u64 id)
1481 {
1482 union {
1483 struct {
1484 struct perf_record_header_attr attr;
1485 u64 ids[1];
1486 } attr_id;
1487 union perf_event ev;
1488 } ev = {
1489 .attr_id.attr.header.type = PERF_RECORD_HEADER_ATTR,
1490 .attr_id.attr.header.size = sizeof(ev.attr_id),
1491 .attr_id.ids[0] = id,
1492 };
1493
1494 if (attr->size != sizeof(ev.attr_id.attr.attr)) {
1495 pr_debug("Unexpected perf_event_attr size\n");
1496 return -EINVAL;
1497 }
1498 ev.attr_id.attr.attr = *attr;
1499 return perf_session__deliver_synth_event(session, &ev.ev, NULL);
1500 }
1501
event_swap(union perf_event * event,bool sample_id_all)1502 static void event_swap(union perf_event *event, bool sample_id_all)
1503 {
1504 perf_event__swap_op swap;
1505
1506 swap = perf_event__swap_ops[event->header.type];
1507 if (swap)
1508 swap(event, sample_id_all);
1509 }
1510
perf_session__peek_event(struct perf_session * session,off_t file_offset,void * buf,size_t buf_sz,union perf_event ** event_ptr,struct perf_sample * sample)1511 int perf_session__peek_event(struct perf_session *session, off_t file_offset,
1512 void *buf, size_t buf_sz,
1513 union perf_event **event_ptr,
1514 struct perf_sample *sample)
1515 {
1516 union perf_event *event;
1517 size_t hdr_sz, rest;
1518 int fd;
1519
1520 if (session->one_mmap && !session->header.needs_swap) {
1521 event = file_offset - session->one_mmap_offset +
1522 session->one_mmap_addr;
1523 goto out_parse_sample;
1524 }
1525
1526 if (perf_data__is_pipe(session->data))
1527 return -1;
1528
1529 fd = perf_data__fd(session->data);
1530 hdr_sz = sizeof(struct perf_event_header);
1531
1532 if (buf_sz < hdr_sz)
1533 return -1;
1534
1535 if (lseek(fd, file_offset, SEEK_SET) == (off_t)-1 ||
1536 readn(fd, buf, hdr_sz) != (ssize_t)hdr_sz)
1537 return -1;
1538
1539 event = (union perf_event *)buf;
1540
1541 if (session->header.needs_swap)
1542 perf_event_header__bswap(&event->header);
1543
1544 if (event->header.size < hdr_sz || event->header.size > buf_sz)
1545 return -1;
1546
1547 buf += hdr_sz;
1548 rest = event->header.size - hdr_sz;
1549
1550 if (readn(fd, buf, rest) != (ssize_t)rest)
1551 return -1;
1552
1553 if (session->header.needs_swap)
1554 event_swap(event, evlist__sample_id_all(session->evlist));
1555
1556 out_parse_sample:
1557
1558 if (sample && event->header.type < PERF_RECORD_USER_TYPE_START &&
1559 evlist__parse_sample(session->evlist, event, sample))
1560 return -1;
1561
1562 *event_ptr = event;
1563
1564 return 0;
1565 }
1566
perf_session__peek_events(struct perf_session * session,u64 offset,u64 size,peek_events_cb_t cb,void * data)1567 int perf_session__peek_events(struct perf_session *session, u64 offset,
1568 u64 size, peek_events_cb_t cb, void *data)
1569 {
1570 u64 max_offset = offset + size;
1571 char buf[PERF_SAMPLE_MAX_SIZE];
1572 union perf_event *event;
1573 int err;
1574
1575 do {
1576 err = perf_session__peek_event(session, offset, buf,
1577 PERF_SAMPLE_MAX_SIZE, &event,
1578 NULL);
1579 if (err)
1580 return err;
1581
1582 err = cb(session, event, offset, data);
1583 if (err)
1584 return err;
1585
1586 offset += event->header.size;
1587 if (event->header.type == PERF_RECORD_AUXTRACE)
1588 offset += event->auxtrace.size;
1589
1590 } while (offset < max_offset);
1591
1592 return err;
1593 }
1594
perf_session__process_event(struct perf_session * session,union perf_event * event,u64 file_offset,const char * file_path)1595 static s64 perf_session__process_event(struct perf_session *session,
1596 union perf_event *event, u64 file_offset,
1597 const char *file_path)
1598 {
1599 struct evlist *evlist = session->evlist;
1600 const struct perf_tool *tool = session->tool;
1601 int ret;
1602
1603 if (session->header.needs_swap)
1604 event_swap(event, evlist__sample_id_all(evlist));
1605
1606 if (event->header.type >= PERF_RECORD_HEADER_MAX)
1607 return -EINVAL;
1608
1609 events_stats__inc(&evlist->stats, event->header.type);
1610
1611 if (event->header.type >= PERF_RECORD_USER_TYPE_START)
1612 return perf_session__process_user_event(session, event, file_offset, file_path);
1613
1614 if (tool->ordered_events) {
1615 u64 timestamp = -1ULL;
1616
1617 ret = evlist__parse_sample_timestamp(evlist, event, ×tamp);
1618 if (ret && ret != -1)
1619 return ret;
1620
1621 ret = perf_session__queue_event(session, event, timestamp, file_offset, file_path);
1622 if (ret != -ETIME)
1623 return ret;
1624 }
1625
1626 return perf_session__deliver_event(session, event, tool, file_offset, file_path);
1627 }
1628
perf_event_header__bswap(struct perf_event_header * hdr)1629 void perf_event_header__bswap(struct perf_event_header *hdr)
1630 {
1631 hdr->type = bswap_32(hdr->type);
1632 hdr->misc = bswap_16(hdr->misc);
1633 hdr->size = bswap_16(hdr->size);
1634 }
1635
perf_session__findnew(struct perf_session * session,pid_t pid)1636 struct thread *perf_session__findnew(struct perf_session *session, pid_t pid)
1637 {
1638 return machine__findnew_thread(&session->machines.host, -1, pid);
1639 }
1640
perf_session__register_idle_thread(struct perf_session * session)1641 int perf_session__register_idle_thread(struct perf_session *session)
1642 {
1643 struct thread *thread = machine__idle_thread(&session->machines.host);
1644
1645 /* machine__idle_thread() got the thread, so put it */
1646 thread__put(thread);
1647 return thread ? 0 : -1;
1648 }
1649
1650 static void
perf_session__warn_order(const struct perf_session * session)1651 perf_session__warn_order(const struct perf_session *session)
1652 {
1653 const struct ordered_events *oe = &session->ordered_events;
1654 struct evsel *evsel;
1655 bool should_warn = true;
1656
1657 evlist__for_each_entry(session->evlist, evsel) {
1658 if (evsel->core.attr.write_backward)
1659 should_warn = false;
1660 }
1661
1662 if (!should_warn)
1663 return;
1664 if (oe->nr_unordered_events != 0)
1665 ui__warning("%u out of order events recorded.\n", oe->nr_unordered_events);
1666 }
1667
perf_session__warn_about_errors(const struct perf_session * session)1668 static void perf_session__warn_about_errors(const struct perf_session *session)
1669 {
1670 const struct events_stats *stats = &session->evlist->stats;
1671
1672 if (session->tool->lost == perf_event__process_lost &&
1673 stats->nr_events[PERF_RECORD_LOST] != 0) {
1674 ui__warning("Processed %d events and lost %d chunks!\n\n"
1675 "Check IO/CPU overload!\n\n",
1676 stats->nr_events[0],
1677 stats->nr_events[PERF_RECORD_LOST]);
1678 }
1679
1680 if (session->tool->lost_samples == perf_event__process_lost_samples) {
1681 double drop_rate;
1682
1683 drop_rate = (double)stats->total_lost_samples /
1684 (double) (stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples);
1685 if (drop_rate > 0.05) {
1686 ui__warning("Processed %" PRIu64 " samples and lost %3.2f%%!\n\n",
1687 stats->nr_events[PERF_RECORD_SAMPLE] + stats->total_lost_samples,
1688 drop_rate * 100.0);
1689 }
1690 }
1691
1692 if (session->tool->aux == perf_event__process_aux &&
1693 stats->total_aux_lost != 0) {
1694 ui__warning("AUX data lost %" PRIu64 " times out of %u!\n\n",
1695 stats->total_aux_lost,
1696 stats->nr_events[PERF_RECORD_AUX]);
1697 }
1698
1699 if (session->tool->aux == perf_event__process_aux &&
1700 stats->total_aux_partial != 0) {
1701 bool vmm_exclusive = false;
1702
1703 (void)sysfs__read_bool("module/kvm_intel/parameters/vmm_exclusive",
1704 &vmm_exclusive);
1705
1706 ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
1707 "Are you running a KVM guest in the background?%s\n\n",
1708 stats->total_aux_partial,
1709 stats->nr_events[PERF_RECORD_AUX],
1710 vmm_exclusive ?
1711 "\nReloading kvm_intel module with vmm_exclusive=0\n"
1712 "will reduce the gaps to only guest's timeslices." :
1713 "");
1714 }
1715
1716 if (session->tool->aux == perf_event__process_aux &&
1717 stats->total_aux_collision != 0) {
1718 ui__warning("AUX data detected collision %" PRIu64 " times out of %u!\n\n",
1719 stats->total_aux_collision,
1720 stats->nr_events[PERF_RECORD_AUX]);
1721 }
1722
1723 if (stats->nr_unknown_events != 0) {
1724 ui__warning("Found %u unknown events!\n\n"
1725 "Is this an older tool processing a perf.data "
1726 "file generated by a more recent tool?\n\n"
1727 "If that is not the case, consider "
1728 "reporting to [email protected].\n\n",
1729 stats->nr_unknown_events);
1730 }
1731
1732 if (stats->nr_unknown_id != 0) {
1733 ui__warning("%u samples with id not present in the header\n",
1734 stats->nr_unknown_id);
1735 }
1736
1737 if (stats->nr_invalid_chains != 0) {
1738 ui__warning("Found invalid callchains!\n\n"
1739 "%u out of %u events were discarded for this reason.\n\n"
1740 "Consider reporting to [email protected].\n\n",
1741 stats->nr_invalid_chains,
1742 stats->nr_events[PERF_RECORD_SAMPLE]);
1743 }
1744
1745 if (stats->nr_unprocessable_samples != 0) {
1746 ui__warning("%u unprocessable samples recorded.\n"
1747 "Do you have a KVM guest running and not using 'perf kvm'?\n",
1748 stats->nr_unprocessable_samples);
1749 }
1750
1751 perf_session__warn_order(session);
1752
1753 events_stats__auxtrace_error_warn(stats);
1754
1755 if (stats->nr_proc_map_timeout != 0) {
1756 ui__warning("%d map information files for pre-existing threads were\n"
1757 "not processed, if there are samples for addresses they\n"
1758 "will not be resolved, you may find out which are these\n"
1759 "threads by running with -v and redirecting the output\n"
1760 "to a file.\n"
1761 "The time limit to process proc map is too short?\n"
1762 "Increase it by --proc-map-timeout\n",
1763 stats->nr_proc_map_timeout);
1764 }
1765 }
1766
perf_session__flush_thread_stack(struct thread * thread,void * p __maybe_unused)1767 static int perf_session__flush_thread_stack(struct thread *thread,
1768 void *p __maybe_unused)
1769 {
1770 return thread_stack__flush(thread);
1771 }
1772
perf_session__flush_thread_stacks(struct perf_session * session)1773 static int perf_session__flush_thread_stacks(struct perf_session *session)
1774 {
1775 return machines__for_each_thread(&session->machines,
1776 perf_session__flush_thread_stack,
1777 NULL);
1778 }
1779
1780 volatile sig_atomic_t session_done;
1781
1782 static int __perf_session__process_decomp_events(struct perf_session *session);
1783
__perf_session__process_pipe_events(struct perf_session * session)1784 static int __perf_session__process_pipe_events(struct perf_session *session)
1785 {
1786 struct ordered_events *oe = &session->ordered_events;
1787 const struct perf_tool *tool = session->tool;
1788 struct ui_progress prog;
1789 union perf_event *event;
1790 uint32_t size, cur_size = 0;
1791 void *buf = NULL;
1792 s64 skip = 0;
1793 u64 head;
1794 ssize_t err;
1795 void *p;
1796 bool update_prog = false;
1797
1798 /*
1799 * If it's from a file saving pipe data (by redirection), it would have
1800 * a file name other than "-". Then we can get the total size and show
1801 * the progress.
1802 */
1803 if (strcmp(session->data->path, "-") && session->data->file.size) {
1804 ui_progress__init_size(&prog, session->data->file.size,
1805 "Processing events...");
1806 update_prog = true;
1807 }
1808
1809 head = 0;
1810 cur_size = sizeof(union perf_event);
1811
1812 buf = malloc(cur_size);
1813 if (!buf)
1814 return -errno;
1815 ordered_events__set_copy_on_queue(oe, true);
1816 more:
1817 event = buf;
1818 err = perf_data__read(session->data, event,
1819 sizeof(struct perf_event_header));
1820 if (err <= 0) {
1821 if (err == 0)
1822 goto done;
1823
1824 pr_err("failed to read event header\n");
1825 goto out_err;
1826 }
1827
1828 if (session->header.needs_swap)
1829 perf_event_header__bswap(&event->header);
1830
1831 size = event->header.size;
1832 if (size < sizeof(struct perf_event_header)) {
1833 pr_err("bad event header size\n");
1834 goto out_err;
1835 }
1836
1837 if (size > cur_size) {
1838 void *new = realloc(buf, size);
1839 if (!new) {
1840 pr_err("failed to allocate memory to read event\n");
1841 goto out_err;
1842 }
1843 buf = new;
1844 cur_size = size;
1845 event = buf;
1846 }
1847 p = event;
1848 p += sizeof(struct perf_event_header);
1849
1850 if (size - sizeof(struct perf_event_header)) {
1851 err = perf_data__read(session->data, p,
1852 size - sizeof(struct perf_event_header));
1853 if (err <= 0) {
1854 if (err == 0) {
1855 pr_err("unexpected end of event stream\n");
1856 goto done;
1857 }
1858
1859 pr_err("failed to read event data\n");
1860 goto out_err;
1861 }
1862 }
1863
1864 if ((skip = perf_session__process_event(session, event, head, "pipe")) < 0) {
1865 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
1866 head, event->header.size, event->header.type);
1867 err = -EINVAL;
1868 goto out_err;
1869 }
1870
1871 head += size;
1872
1873 if (skip > 0)
1874 head += skip;
1875
1876 err = __perf_session__process_decomp_events(session);
1877 if (err)
1878 goto out_err;
1879
1880 if (update_prog)
1881 ui_progress__update(&prog, size);
1882
1883 if (!session_done())
1884 goto more;
1885 done:
1886 /* do the final flush for ordered samples */
1887 err = ordered_events__flush(oe, OE_FLUSH__FINAL);
1888 if (err)
1889 goto out_err;
1890 err = auxtrace__flush_events(session, tool);
1891 if (err)
1892 goto out_err;
1893 err = perf_session__flush_thread_stacks(session);
1894 out_err:
1895 free(buf);
1896 if (update_prog)
1897 ui_progress__finish();
1898 if (!tool->no_warn)
1899 perf_session__warn_about_errors(session);
1900 ordered_events__free(&session->ordered_events);
1901 auxtrace__free_events(session);
1902 return err;
1903 }
1904
1905 static union perf_event *
prefetch_event(char * buf,u64 head,size_t mmap_size,bool needs_swap,union perf_event * error)1906 prefetch_event(char *buf, u64 head, size_t mmap_size,
1907 bool needs_swap, union perf_event *error)
1908 {
1909 union perf_event *event;
1910 u16 event_size;
1911
1912 /*
1913 * Ensure we have enough space remaining to read
1914 * the size of the event in the headers.
1915 */
1916 if (head + sizeof(event->header) > mmap_size)
1917 return NULL;
1918
1919 event = (union perf_event *)(buf + head);
1920 if (needs_swap)
1921 perf_event_header__bswap(&event->header);
1922
1923 event_size = event->header.size;
1924 if (head + event_size <= mmap_size)
1925 return event;
1926
1927 /* We're not fetching the event so swap back again */
1928 if (needs_swap)
1929 perf_event_header__bswap(&event->header);
1930
1931 /* Check if the event fits into the next mmapped buf. */
1932 if (event_size <= mmap_size - head % page_size) {
1933 /* Remap buf and fetch again. */
1934 return NULL;
1935 }
1936
1937 /* Invalid input. Event size should never exceed mmap_size. */
1938 pr_debug("%s: head=%#" PRIx64 " event->header.size=%#x, mmap_size=%#zx:"
1939 " fuzzed or compressed perf.data?\n", __func__, head, event_size, mmap_size);
1940
1941 return error;
1942 }
1943
1944 static union perf_event *
fetch_mmaped_event(u64 head,size_t mmap_size,char * buf,bool needs_swap)1945 fetch_mmaped_event(u64 head, size_t mmap_size, char *buf, bool needs_swap)
1946 {
1947 return prefetch_event(buf, head, mmap_size, needs_swap, ERR_PTR(-EINVAL));
1948 }
1949
1950 static union perf_event *
fetch_decomp_event(u64 head,size_t mmap_size,char * buf,bool needs_swap)1951 fetch_decomp_event(u64 head, size_t mmap_size, char *buf, bool needs_swap)
1952 {
1953 return prefetch_event(buf, head, mmap_size, needs_swap, NULL);
1954 }
1955
__perf_session__process_decomp_events(struct perf_session * session)1956 static int __perf_session__process_decomp_events(struct perf_session *session)
1957 {
1958 s64 skip;
1959 u64 size;
1960 struct decomp *decomp = session->active_decomp->decomp_last;
1961
1962 if (!decomp)
1963 return 0;
1964
1965 while (decomp->head < decomp->size && !session_done()) {
1966 union perf_event *event = fetch_decomp_event(decomp->head, decomp->size, decomp->data,
1967 session->header.needs_swap);
1968
1969 if (!event)
1970 break;
1971
1972 size = event->header.size;
1973
1974 if (size < sizeof(struct perf_event_header) ||
1975 (skip = perf_session__process_event(session, event, decomp->file_pos,
1976 decomp->file_path)) < 0) {
1977 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n",
1978 decomp->file_pos + decomp->head, event->header.size, event->header.type);
1979 return -EINVAL;
1980 }
1981
1982 if (skip)
1983 size += skip;
1984
1985 decomp->head += size;
1986 }
1987
1988 return 0;
1989 }
1990
1991 /*
1992 * On 64bit we can mmap the data file in one go. No need for tiny mmap
1993 * slices. On 32bit we use 32MB.
1994 */
1995 #if BITS_PER_LONG == 64
1996 #define MMAP_SIZE ULLONG_MAX
1997 #define NUM_MMAPS 1
1998 #else
1999 #define MMAP_SIZE (32 * 1024 * 1024ULL)
2000 #define NUM_MMAPS 128
2001 #endif
2002
2003 struct reader;
2004
2005 typedef s64 (*reader_cb_t)(struct perf_session *session,
2006 union perf_event *event,
2007 u64 file_offset,
2008 const char *file_path);
2009
2010 struct reader {
2011 int fd;
2012 const char *path;
2013 u64 data_size;
2014 u64 data_offset;
2015 reader_cb_t process;
2016 bool in_place_update;
2017 char *mmaps[NUM_MMAPS];
2018 size_t mmap_size;
2019 int mmap_idx;
2020 char *mmap_cur;
2021 u64 file_pos;
2022 u64 file_offset;
2023 u64 head;
2024 u64 size;
2025 bool done;
2026 struct zstd_data zstd_data;
2027 struct decomp_data decomp_data;
2028 };
2029
2030 static int
reader__init(struct reader * rd,bool * one_mmap)2031 reader__init(struct reader *rd, bool *one_mmap)
2032 {
2033 u64 data_size = rd->data_size;
2034 char **mmaps = rd->mmaps;
2035
2036 rd->head = rd->data_offset;
2037 data_size += rd->data_offset;
2038
2039 rd->mmap_size = MMAP_SIZE;
2040 if (rd->mmap_size > data_size) {
2041 rd->mmap_size = data_size;
2042 if (one_mmap)
2043 *one_mmap = true;
2044 }
2045
2046 memset(mmaps, 0, sizeof(rd->mmaps));
2047
2048 if (zstd_init(&rd->zstd_data, 0))
2049 return -1;
2050 rd->decomp_data.zstd_decomp = &rd->zstd_data;
2051
2052 return 0;
2053 }
2054
2055 static void
reader__release_decomp(struct reader * rd)2056 reader__release_decomp(struct reader *rd)
2057 {
2058 perf_decomp__release_events(rd->decomp_data.decomp);
2059 zstd_fini(&rd->zstd_data);
2060 }
2061
2062 static int
reader__mmap(struct reader * rd,struct perf_session * session)2063 reader__mmap(struct reader *rd, struct perf_session *session)
2064 {
2065 int mmap_prot, mmap_flags;
2066 char *buf, **mmaps = rd->mmaps;
2067 u64 page_offset;
2068
2069 mmap_prot = PROT_READ;
2070 mmap_flags = MAP_SHARED;
2071
2072 if (rd->in_place_update) {
2073 mmap_prot |= PROT_WRITE;
2074 } else if (session->header.needs_swap) {
2075 mmap_prot |= PROT_WRITE;
2076 mmap_flags = MAP_PRIVATE;
2077 }
2078
2079 if (mmaps[rd->mmap_idx]) {
2080 munmap(mmaps[rd->mmap_idx], rd->mmap_size);
2081 mmaps[rd->mmap_idx] = NULL;
2082 }
2083
2084 page_offset = page_size * (rd->head / page_size);
2085 rd->file_offset += page_offset;
2086 rd->head -= page_offset;
2087
2088 buf = mmap(NULL, rd->mmap_size, mmap_prot, mmap_flags, rd->fd,
2089 rd->file_offset);
2090 if (buf == MAP_FAILED) {
2091 pr_err("failed to mmap file\n");
2092 return -errno;
2093 }
2094 mmaps[rd->mmap_idx] = rd->mmap_cur = buf;
2095 rd->mmap_idx = (rd->mmap_idx + 1) & (ARRAY_SIZE(rd->mmaps) - 1);
2096 rd->file_pos = rd->file_offset + rd->head;
2097 if (session->one_mmap) {
2098 session->one_mmap_addr = buf;
2099 session->one_mmap_offset = rd->file_offset;
2100 }
2101
2102 return 0;
2103 }
2104
2105 enum {
2106 READER_OK,
2107 READER_NODATA,
2108 };
2109
2110 static int
reader__read_event(struct reader * rd,struct perf_session * session,struct ui_progress * prog)2111 reader__read_event(struct reader *rd, struct perf_session *session,
2112 struct ui_progress *prog)
2113 {
2114 u64 size;
2115 int err = READER_OK;
2116 union perf_event *event;
2117 s64 skip;
2118
2119 event = fetch_mmaped_event(rd->head, rd->mmap_size, rd->mmap_cur,
2120 session->header.needs_swap);
2121 if (IS_ERR(event))
2122 return PTR_ERR(event);
2123
2124 if (!event)
2125 return READER_NODATA;
2126
2127 size = event->header.size;
2128
2129 skip = -EINVAL;
2130
2131 if (size < sizeof(struct perf_event_header) ||
2132 (skip = rd->process(session, event, rd->file_pos, rd->path)) < 0) {
2133 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d [%s]\n",
2134 rd->file_offset + rd->head, event->header.size,
2135 event->header.type, strerror(-skip));
2136 err = skip;
2137 goto out;
2138 }
2139
2140 if (skip)
2141 size += skip;
2142
2143 rd->size += size;
2144 rd->head += size;
2145 rd->file_pos += size;
2146
2147 err = __perf_session__process_decomp_events(session);
2148 if (err)
2149 goto out;
2150
2151 ui_progress__update(prog, size);
2152
2153 out:
2154 return err;
2155 }
2156
2157 static inline bool
reader__eof(struct reader * rd)2158 reader__eof(struct reader *rd)
2159 {
2160 return (rd->file_pos >= rd->data_size + rd->data_offset);
2161 }
2162
2163 static int
reader__process_events(struct reader * rd,struct perf_session * session,struct ui_progress * prog)2164 reader__process_events(struct reader *rd, struct perf_session *session,
2165 struct ui_progress *prog)
2166 {
2167 int err;
2168
2169 err = reader__init(rd, &session->one_mmap);
2170 if (err)
2171 goto out;
2172
2173 session->active_decomp = &rd->decomp_data;
2174
2175 remap:
2176 err = reader__mmap(rd, session);
2177 if (err)
2178 goto out;
2179
2180 more:
2181 err = reader__read_event(rd, session, prog);
2182 if (err < 0)
2183 goto out;
2184 else if (err == READER_NODATA)
2185 goto remap;
2186
2187 if (session_done())
2188 goto out;
2189
2190 if (!reader__eof(rd))
2191 goto more;
2192
2193 out:
2194 session->active_decomp = &session->decomp_data;
2195 return err;
2196 }
2197
process_simple(struct perf_session * session,union perf_event * event,u64 file_offset,const char * file_path)2198 static s64 process_simple(struct perf_session *session,
2199 union perf_event *event,
2200 u64 file_offset,
2201 const char *file_path)
2202 {
2203 return perf_session__process_event(session, event, file_offset, file_path);
2204 }
2205
__perf_session__process_events(struct perf_session * session)2206 static int __perf_session__process_events(struct perf_session *session)
2207 {
2208 struct reader rd = {
2209 .fd = perf_data__fd(session->data),
2210 .path = session->data->file.path,
2211 .data_size = session->header.data_size,
2212 .data_offset = session->header.data_offset,
2213 .process = process_simple,
2214 .in_place_update = session->data->in_place_update,
2215 };
2216 struct ordered_events *oe = &session->ordered_events;
2217 const struct perf_tool *tool = session->tool;
2218 struct ui_progress prog;
2219 int err;
2220
2221 if (rd.data_size == 0)
2222 return -1;
2223
2224 ui_progress__init_size(&prog, rd.data_size, "Processing events...");
2225
2226 err = reader__process_events(&rd, session, &prog);
2227 if (err)
2228 goto out_err;
2229 /* do the final flush for ordered samples */
2230 err = ordered_events__flush(oe, OE_FLUSH__FINAL);
2231 if (err)
2232 goto out_err;
2233 err = auxtrace__flush_events(session, tool);
2234 if (err)
2235 goto out_err;
2236 err = perf_session__flush_thread_stacks(session);
2237 out_err:
2238 ui_progress__finish();
2239 if (!tool->no_warn)
2240 perf_session__warn_about_errors(session);
2241 /*
2242 * We may switching perf.data output, make ordered_events
2243 * reusable.
2244 */
2245 ordered_events__reinit(&session->ordered_events);
2246 auxtrace__free_events(session);
2247 reader__release_decomp(&rd);
2248 session->one_mmap = false;
2249 return err;
2250 }
2251
2252 /*
2253 * Processing 2 MB of data from each reader in sequence,
2254 * because that's the way the ordered events sorting works
2255 * most efficiently.
2256 */
2257 #define READER_MAX_SIZE (2 * 1024 * 1024)
2258
2259 /*
2260 * This function reads, merge and process directory data.
2261 * It assumens the version 1 of directory data, where each
2262 * data file holds per-cpu data, already sorted by kernel.
2263 */
__perf_session__process_dir_events(struct perf_session * session)2264 static int __perf_session__process_dir_events(struct perf_session *session)
2265 {
2266 struct perf_data *data = session->data;
2267 const struct perf_tool *tool = session->tool;
2268 int i, ret, readers, nr_readers;
2269 struct ui_progress prog;
2270 u64 total_size = perf_data__size(session->data);
2271 struct reader *rd;
2272
2273 ui_progress__init_size(&prog, total_size, "Processing events...");
2274
2275 nr_readers = 1;
2276 for (i = 0; i < data->dir.nr; i++) {
2277 if (data->dir.files[i].size)
2278 nr_readers++;
2279 }
2280
2281 rd = zalloc(nr_readers * sizeof(struct reader));
2282 if (!rd)
2283 return -ENOMEM;
2284
2285 rd[0] = (struct reader) {
2286 .fd = perf_data__fd(session->data),
2287 .path = session->data->file.path,
2288 .data_size = session->header.data_size,
2289 .data_offset = session->header.data_offset,
2290 .process = process_simple,
2291 .in_place_update = session->data->in_place_update,
2292 };
2293 ret = reader__init(&rd[0], NULL);
2294 if (ret)
2295 goto out_err;
2296 ret = reader__mmap(&rd[0], session);
2297 if (ret)
2298 goto out_err;
2299 readers = 1;
2300
2301 for (i = 0; i < data->dir.nr; i++) {
2302 if (!data->dir.files[i].size)
2303 continue;
2304 rd[readers] = (struct reader) {
2305 .fd = data->dir.files[i].fd,
2306 .path = data->dir.files[i].path,
2307 .data_size = data->dir.files[i].size,
2308 .data_offset = 0,
2309 .process = process_simple,
2310 .in_place_update = session->data->in_place_update,
2311 };
2312 ret = reader__init(&rd[readers], NULL);
2313 if (ret)
2314 goto out_err;
2315 ret = reader__mmap(&rd[readers], session);
2316 if (ret)
2317 goto out_err;
2318 readers++;
2319 }
2320
2321 i = 0;
2322 while (readers) {
2323 if (session_done())
2324 break;
2325
2326 if (rd[i].done) {
2327 i = (i + 1) % nr_readers;
2328 continue;
2329 }
2330 if (reader__eof(&rd[i])) {
2331 rd[i].done = true;
2332 readers--;
2333 continue;
2334 }
2335
2336 session->active_decomp = &rd[i].decomp_data;
2337 ret = reader__read_event(&rd[i], session, &prog);
2338 if (ret < 0) {
2339 goto out_err;
2340 } else if (ret == READER_NODATA) {
2341 ret = reader__mmap(&rd[i], session);
2342 if (ret)
2343 goto out_err;
2344 }
2345
2346 if (rd[i].size >= READER_MAX_SIZE) {
2347 rd[i].size = 0;
2348 i = (i + 1) % nr_readers;
2349 }
2350 }
2351
2352 ret = ordered_events__flush(&session->ordered_events, OE_FLUSH__FINAL);
2353 if (ret)
2354 goto out_err;
2355
2356 ret = perf_session__flush_thread_stacks(session);
2357 out_err:
2358 ui_progress__finish();
2359
2360 if (!tool->no_warn)
2361 perf_session__warn_about_errors(session);
2362
2363 /*
2364 * We may switching perf.data output, make ordered_events
2365 * reusable.
2366 */
2367 ordered_events__reinit(&session->ordered_events);
2368
2369 session->one_mmap = false;
2370
2371 session->active_decomp = &session->decomp_data;
2372 for (i = 0; i < nr_readers; i++)
2373 reader__release_decomp(&rd[i]);
2374 zfree(&rd);
2375
2376 return ret;
2377 }
2378
perf_session__process_events(struct perf_session * session)2379 int perf_session__process_events(struct perf_session *session)
2380 {
2381 if (perf_session__register_idle_thread(session) < 0)
2382 return -ENOMEM;
2383
2384 if (perf_data__is_pipe(session->data))
2385 return __perf_session__process_pipe_events(session);
2386
2387 if (perf_data__is_dir(session->data) && session->data->dir.nr)
2388 return __perf_session__process_dir_events(session);
2389
2390 return __perf_session__process_events(session);
2391 }
2392
perf_session__has_traces(struct perf_session * session,const char * msg)2393 bool perf_session__has_traces(struct perf_session *session, const char *msg)
2394 {
2395 struct evsel *evsel;
2396
2397 evlist__for_each_entry(session->evlist, evsel) {
2398 if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT)
2399 return true;
2400 }
2401
2402 pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg);
2403 return false;
2404 }
2405
map__set_kallsyms_ref_reloc_sym(struct map * map,const char * symbol_name,u64 addr)2406 int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u64 addr)
2407 {
2408 char *bracket;
2409 struct ref_reloc_sym *ref;
2410 struct kmap *kmap;
2411
2412 ref = zalloc(sizeof(struct ref_reloc_sym));
2413 if (ref == NULL)
2414 return -ENOMEM;
2415
2416 ref->name = strdup(symbol_name);
2417 if (ref->name == NULL) {
2418 free(ref);
2419 return -ENOMEM;
2420 }
2421
2422 bracket = strchr(ref->name, ']');
2423 if (bracket)
2424 *bracket = '\0';
2425
2426 ref->addr = addr;
2427
2428 kmap = map__kmap(map);
2429 if (kmap)
2430 kmap->ref_reloc_sym = ref;
2431
2432 return 0;
2433 }
2434
perf_session__fprintf_dsos(struct perf_session * session,FILE * fp)2435 size_t perf_session__fprintf_dsos(struct perf_session *session, FILE *fp)
2436 {
2437 return machines__fprintf_dsos(&session->machines, fp);
2438 }
2439
perf_session__fprintf_dsos_buildid(struct perf_session * session,FILE * fp,bool (skip)(struct dso * dso,int parm),int parm)2440 size_t perf_session__fprintf_dsos_buildid(struct perf_session *session, FILE *fp,
2441 bool (skip)(struct dso *dso, int parm), int parm)
2442 {
2443 return machines__fprintf_dsos_buildid(&session->machines, fp, skip, parm);
2444 }
2445
perf_session__fprintf_nr_events(struct perf_session * session,FILE * fp)2446 size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
2447 {
2448 size_t ret;
2449 const char *msg = "";
2450
2451 if (perf_header__has_feat(&session->header, HEADER_AUXTRACE))
2452 msg = " (excludes AUX area (e.g. instruction trace) decoded / synthesized events)";
2453
2454 ret = fprintf(fp, "\nAggregated stats:%s\n", msg);
2455
2456 ret += events_stats__fprintf(&session->evlist->stats, fp);
2457 return ret;
2458 }
2459
perf_session__fprintf(struct perf_session * session,FILE * fp)2460 size_t perf_session__fprintf(struct perf_session *session, FILE *fp)
2461 {
2462 /*
2463 * FIXME: Here we have to actually print all the machines in this
2464 * session, not just the host...
2465 */
2466 return machine__fprintf(&session->machines.host, fp);
2467 }
2468
perf_session__dump_kmaps(struct perf_session * session)2469 void perf_session__dump_kmaps(struct perf_session *session)
2470 {
2471 int save_verbose = verbose;
2472
2473 fflush(stdout);
2474 fprintf(stderr, "Kernel and module maps:\n");
2475 verbose = 0; /* Suppress verbose to print a summary only */
2476 maps__fprintf(machine__kernel_maps(&session->machines.host), stderr);
2477 verbose = save_verbose;
2478 }
2479
perf_session__find_first_evtype(struct perf_session * session,unsigned int type)2480 struct evsel *perf_session__find_first_evtype(struct perf_session *session,
2481 unsigned int type)
2482 {
2483 struct evsel *pos;
2484
2485 evlist__for_each_entry(session->evlist, pos) {
2486 if (pos->core.attr.type == type)
2487 return pos;
2488 }
2489 return NULL;
2490 }
2491
perf_session__cpu_bitmap(struct perf_session * session,const char * cpu_list,unsigned long * cpu_bitmap)2492 int perf_session__cpu_bitmap(struct perf_session *session,
2493 const char *cpu_list, unsigned long *cpu_bitmap)
2494 {
2495 int i, err = -1;
2496 struct perf_cpu_map *map;
2497 int nr_cpus = min(session->header.env.nr_cpus_avail, MAX_NR_CPUS);
2498 struct perf_cpu cpu;
2499
2500 for (i = 0; i < PERF_TYPE_MAX; ++i) {
2501 struct evsel *evsel;
2502
2503 evsel = perf_session__find_first_evtype(session, i);
2504 if (!evsel)
2505 continue;
2506
2507 if (!(evsel->core.attr.sample_type & PERF_SAMPLE_CPU)) {
2508 pr_err("File does not contain CPU events. "
2509 "Remove -C option to proceed.\n");
2510 return -1;
2511 }
2512 }
2513
2514 map = perf_cpu_map__new(cpu_list);
2515 if (map == NULL) {
2516 pr_err("Invalid cpu_list\n");
2517 return -1;
2518 }
2519
2520 perf_cpu_map__for_each_cpu(cpu, i, map) {
2521 if (cpu.cpu >= nr_cpus) {
2522 pr_err("Requested CPU %d too large. "
2523 "Consider raising MAX_NR_CPUS\n", cpu.cpu);
2524 goto out_delete_map;
2525 }
2526
2527 __set_bit(cpu.cpu, cpu_bitmap);
2528 }
2529
2530 err = 0;
2531
2532 out_delete_map:
2533 perf_cpu_map__put(map);
2534 return err;
2535 }
2536
perf_session__fprintf_info(struct perf_session * session,FILE * fp,bool full)2537 void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
2538 bool full)
2539 {
2540 if (session == NULL || fp == NULL)
2541 return;
2542
2543 fprintf(fp, "# ========\n");
2544 perf_header__fprintf_info(session, fp, full);
2545 fprintf(fp, "# ========\n#\n");
2546 }
2547
perf_session__register_guest(struct perf_session * session,pid_t machine_pid)2548 static int perf_session__register_guest(struct perf_session *session, pid_t machine_pid)
2549 {
2550 struct machine *machine = machines__findnew(&session->machines, machine_pid);
2551 struct thread *thread;
2552
2553 if (!machine)
2554 return -ENOMEM;
2555
2556 machine->single_address_space = session->machines.host.single_address_space;
2557
2558 thread = machine__idle_thread(machine);
2559 if (!thread)
2560 return -ENOMEM;
2561 thread__put(thread);
2562
2563 machine->kallsyms_filename = perf_data__guest_kallsyms_name(session->data, machine_pid);
2564
2565 return 0;
2566 }
2567
perf_session__set_guest_cpu(struct perf_session * session,pid_t pid,pid_t tid,int guest_cpu)2568 static int perf_session__set_guest_cpu(struct perf_session *session, pid_t pid,
2569 pid_t tid, int guest_cpu)
2570 {
2571 struct machine *machine = &session->machines.host;
2572 struct thread *thread = machine__findnew_thread(machine, pid, tid);
2573
2574 if (!thread)
2575 return -ENOMEM;
2576 thread__set_guest_cpu(thread, guest_cpu);
2577 thread__put(thread);
2578
2579 return 0;
2580 }
2581
perf_event__process_id_index(struct perf_session * session,union perf_event * event)2582 int perf_event__process_id_index(struct perf_session *session,
2583 union perf_event *event)
2584 {
2585 struct evlist *evlist = session->evlist;
2586 struct perf_record_id_index *ie = &event->id_index;
2587 size_t sz = ie->header.size - sizeof(*ie);
2588 size_t i, nr, max_nr;
2589 size_t e1_sz = sizeof(struct id_index_entry);
2590 size_t e2_sz = sizeof(struct id_index_entry_2);
2591 size_t etot_sz = e1_sz + e2_sz;
2592 struct id_index_entry_2 *e2;
2593 pid_t last_pid = 0;
2594
2595 max_nr = sz / e1_sz;
2596 nr = ie->nr;
2597 if (nr > max_nr) {
2598 printf("Too big: nr %zu max_nr %zu\n", nr, max_nr);
2599 return -EINVAL;
2600 }
2601
2602 if (sz >= nr * etot_sz) {
2603 max_nr = sz / etot_sz;
2604 if (nr > max_nr) {
2605 printf("Too big2: nr %zu max_nr %zu\n", nr, max_nr);
2606 return -EINVAL;
2607 }
2608 e2 = (void *)ie + sizeof(*ie) + nr * e1_sz;
2609 } else {
2610 e2 = NULL;
2611 }
2612
2613 if (dump_trace)
2614 fprintf(stdout, " nr: %zu\n", nr);
2615
2616 for (i = 0; i < nr; i++, (e2 ? e2++ : 0)) {
2617 struct id_index_entry *e = &ie->entries[i];
2618 struct perf_sample_id *sid;
2619 int ret;
2620
2621 if (dump_trace) {
2622 fprintf(stdout, " ... id: %"PRI_lu64, e->id);
2623 fprintf(stdout, " idx: %"PRI_lu64, e->idx);
2624 fprintf(stdout, " cpu: %"PRI_ld64, e->cpu);
2625 fprintf(stdout, " tid: %"PRI_ld64, e->tid);
2626 if (e2) {
2627 fprintf(stdout, " machine_pid: %"PRI_ld64, e2->machine_pid);
2628 fprintf(stdout, " vcpu: %"PRI_lu64"\n", e2->vcpu);
2629 } else {
2630 fprintf(stdout, "\n");
2631 }
2632 }
2633
2634 sid = evlist__id2sid(evlist, e->id);
2635 if (!sid)
2636 return -ENOENT;
2637
2638 sid->idx = e->idx;
2639 sid->cpu.cpu = e->cpu;
2640 sid->tid = e->tid;
2641
2642 if (!e2)
2643 continue;
2644
2645 sid->machine_pid = e2->machine_pid;
2646 sid->vcpu.cpu = e2->vcpu;
2647
2648 if (!sid->machine_pid)
2649 continue;
2650
2651 if (sid->machine_pid != last_pid) {
2652 ret = perf_session__register_guest(session, sid->machine_pid);
2653 if (ret)
2654 return ret;
2655 last_pid = sid->machine_pid;
2656 perf_guest = true;
2657 }
2658
2659 ret = perf_session__set_guest_cpu(session, sid->machine_pid, e->tid, e2->vcpu);
2660 if (ret)
2661 return ret;
2662 }
2663 return 0;
2664 }
2665
perf_session__dsos_hit_all(struct perf_session * session)2666 int perf_session__dsos_hit_all(struct perf_session *session)
2667 {
2668 struct rb_node *nd;
2669 int err;
2670
2671 err = machine__hit_all_dsos(&session->machines.host);
2672 if (err)
2673 return err;
2674
2675 for (nd = rb_first_cached(&session->machines.guests); nd;
2676 nd = rb_next(nd)) {
2677 struct machine *pos = rb_entry(nd, struct machine, rb_node);
2678
2679 err = machine__hit_all_dsos(pos);
2680 if (err)
2681 return err;
2682 }
2683
2684 return 0;
2685 }
2686