~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/session.c

Version: ~ [ linux-5.19-rc3 ] ~ [ linux-5.18.5 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.48 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.123 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.199 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.248 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.284 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.319 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp