1 #define _FILE_OFFSET_BITS 64
3 #include <linux/kernel.h>
24 struct stat input_stat;
26 if (!
strcmp(self->filename,
"-")) {
28 self->fd = STDIN_FILENO;
31 pr_err(
"incompatible file format (rerun with -v to learn more)");
41 if (err ==
ENOENT && !
strcmp(self->filename,
"perf.data"))
42 pr_err(
" (try 'perf record' first)");
47 if (fstat(self->fd, &input_stat) < 0)
50 if (!force && input_stat.
st_uid && (input_stat.
st_uid != geteuid())) {
51 pr_err(
"file %s not owned by current user or root\n",
57 pr_info(
"zero-sized file (%s), nothing to do!\n",
63 pr_err(
"incompatible file format (rerun with -v to learn more)");
68 pr_err(
"non matching sample_type");
73 pr_err(
"non matching sample_id_all");
77 self->size = input_stat.
st_size;
103 static void perf_session__destroy_kernel_maps(
struct perf_session *
self)
117 if (!filename || !
strlen(filename)) {
121 filename =
"perf.data";
125 self =
zalloc(
sizeof(*
self) + len);
130 memcpy(self->filename, filename, len);
135 #if BITS_PER_LONG == 64
138 self->mmap_window = 32 * 1024 * 1024ULL;
141 self->repipe = repipe;
142 INIT_LIST_HEAD(&self->ordered_samples.samples);
143 INIT_LIST_HEAD(&self->ordered_samples.sample_cache);
144 INIT_LIST_HEAD(&self->ordered_samples.to_free);
149 if (perf_session__open(
self, force) < 0)
163 dump_printf(
"WARNING: No sample_id_all support, falling back to unordered processing\n");
184 static void perf_session__delete_dead_threads(
struct perf_session *session)
189 static void machine__delete_threads(
struct machine *
self)
202 static void perf_session__delete_threads(
struct perf_session *session)
209 perf_session__destroy_kernel_maps(
self);
210 perf_session__delete_dead_threads(
self);
211 perf_session__delete_threads(
self);
220 self->last_match =
NULL;
229 static bool symbol__match_parent_regex(
struct symbol *sym)
237 static const u8 cpumodes[] = {
243 #define NCPUMODES (sizeof(cpumodes)/sizeof(u8))
253 memset(&al, 0,
sizeof(al));
287 for (i = 0; i < bs->
nr; i++) {
288 ip__resolve_ams(
self, thr, &bi[i].
to, bs->
entries[i].to);
289 ip__resolve_ams(
self, thr, &bi[i].
from, bs->
entries[i].from);
295 static int machine__resolve_callchain_sample(
struct machine *
machine,
308 pr_warning(
"corrupted callchain. skipping...\n");
312 for (i = 0; i < chain->
nr; i++) {
319 ip = chain->
ips[chain->
nr - i - 1];
333 pr_debug(
"invalid callchain context: "
348 if (al.sym !=
NULL) {
350 symbol__match_parent_regex(al.sym))
374 struct thread *thread,
383 ret = machine__resolve_callchain_sample(machine, thread,
399 thread, evsel->
attr.sample_regs_user,
404 static int process_event_synth_tracing_data_stub(
union perf_event *
event
425 struct machine *machine __maybe_unused)
434 struct machine *machine __maybe_unused)
456 static int process_finished_round(
struct perf_tool *tool,
460 static void perf_tool__fill_defaults(
struct perf_tool *tool)
463 tool->
sample = process_event_sample_stub;
465 tool->
mmap = process_event_stub;
467 tool->
comm = process_event_stub;
469 tool->
fork = process_event_stub;
471 tool->
exit = process_event_stub;
475 tool->
read = process_event_sample_stub;
477 tool->
throttle = process_event_stub;
481 tool->
attr = process_event_synth_attr_stub;
485 tool->
tracing_data = process_event_synth_tracing_data_stub;
487 tool->
build_id = process_finished_round_stub;
499 while (byte_size > 0) {
501 byte_size -=
sizeof(
u32);
510 while (byte_size > 0) {
512 byte_size -=
sizeof(
u64);
519 void *
end = (
void *) event + event->
header.size;
520 int size = end - data;
526 static void perf_event__all64_swap(
union perf_event *event,
533 static void perf_event__comm_swap(
union perf_event *event,
bool sample_id_all)
535 event->comm.pid = bswap_32(event->
comm.pid);
536 event->comm.tid = bswap_32(event->
comm.tid);
539 void *data = &
event->comm.comm;
542 swap_sample_id_all(event, data);
546 static void perf_event__mmap_swap(
union perf_event *event,
549 event->mmap.pid = bswap_32(event->
mmap.pid);
550 event->mmap.tid = bswap_32(event->
mmap.tid);
551 event->mmap.start = bswap_64(event->
mmap.start);
552 event->mmap.len = bswap_64(event->
mmap.len);
553 event->mmap.pgoff = bswap_64(event->
mmap.pgoff);
556 void *data = &
event->mmap.filename;
559 swap_sample_id_all(event, data);
563 static void perf_event__task_swap(
union perf_event *event,
bool sample_id_all)
565 event->fork.pid = bswap_32(event->
fork.pid);
566 event->fork.tid = bswap_32(event->
fork.tid);
567 event->fork.ppid = bswap_32(event->
fork.ppid);
568 event->fork.ptid = bswap_32(event->
fork.ptid);
569 event->fork.time = bswap_64(event->
fork.time);
572 swap_sample_id_all(event, &event->
fork + 1);
575 static void perf_event__read_swap(
union perf_event *event,
bool sample_id_all)
577 event->read.pid = bswap_32(event->
read.pid);
578 event->read.tid = bswap_32(event->
read.tid);
579 event->read.value = bswap_64(event->
read.value);
580 event->read.time_enabled = bswap_64(event->
read.time_enabled);
581 event->read.time_running = bswap_64(event->
read.time_running);
582 event->read.id = bswap_64(event->
read.id);
585 swap_sample_id_all(event, &event->
read + 1);
588 static u8 revbyte(
u8 b)
590 int rev = (b >> 4) | ((b & 0xf) << 4);
591 rev = ((rev & 0xcc) >> 2) | ((rev & 0x33) << 2);
592 rev = ((rev & 0xaa) >> 1) | ((rev & 0x55) << 1);
610 static void swap_bitfield(
u8 *
p,
unsigned len)
614 for (i = 0; i < len; i++) {
637 static void perf_event__hdr_attr_swap(
union perf_event *event,
644 size =
event->header.size;
645 size -= (
void *)&event->
attr.id - (
void *)
event;
649 static void perf_event__event_type_swap(
union perf_event *event,
652 event->event_type.event_type.event_id =
653 bswap_64(event->
event_type.event_type.event_id);
656 static void perf_event__tracing_data_swap(
union perf_event *event,
659 event->tracing_data.size = bswap_32(event->
tracing_data.size);
687 static void perf_session_free_sample_buffers(
struct perf_session *session)
691 while (!list_empty(&os->
to_free)) {
700 static int perf_session_deliver_event(
struct perf_session *session,
727 pr_err(
"Can't parse sample, err = %d\n", ret);
729 ret = perf_session_deliver_event(s, iter->
event, &
sample, tool,
738 if (++idx >= progress_next) {
741 "Processing time ordered events...");
745 if (list_empty(head)) {
747 }
else if (last_ts <= limit) {
796 static int process_finished_round(
struct perf_tool *tool,
800 int ret = flush_sample_queue(session, tool);
819 list_add(&new->list, &os->
samples);
831 p = sample->
list.next;
842 p = sample->
list.prev;
844 list_add(&new->list, &os->
samples);
849 list_add(&new->list, &sample->
list);
853 #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue))
863 if (!timestamp || timestamp == ~0ULL)
867 printf(
"Warning: Timestamp below last timeslice flush\n");
871 if (!list_empty(sc)) {
891 __queue_event(
new, s);
896 static void callchain__printf(
struct perf_sample *sample)
902 for (i = 0; i < sample->
callchain->nr; i++)
907 static void branch_stack__printf(
struct perf_sample *sample)
927 perf_reg_name(rid), val);
931 static void regs_user__printf(
struct perf_sample *sample,
u64 mask)
935 if (user_regs->
regs) {
937 regs_dump__printf(mask, user_regs->
regs);
947 static void perf_session__print_tstamp(
struct perf_session *session,
955 fputs(
"-1 -1 ", stdout);
978 perf_session__print_tstamp(session, event, sample);
980 printf(
"%#" PRIx64 " [%#x]: PERF_RECORD_%s", file_offset,
996 sample_type = evsel->
attr.sample_type;
999 callchain__printf(sample);
1002 branch_stack__printf(sample);
1005 regs_user__printf(sample, evsel->
attr.sample_regs_user);
1011 static struct machine *
1012 perf_session__find_machine_for_cpumode(
struct perf_session *session,
1023 pid =
event->mmap.pid;
1025 pid =
event->ip.pid;
1027 return perf_session__findnew_machine(session, pid);
1030 return perf_session__find_host_machine(session);
1033 static int perf_session_deliver_event(
struct perf_session *session,
1042 dump_event(session, event, file_offset, sample);
1062 machine = perf_session__find_machine_for_cpumode(session, event);
1064 switch (event->
header.type) {
1066 dump_sample(evsel, event, sample);
1067 if (evsel ==
NULL) {
1068 ++session->
hists.stats.nr_unknown_id;
1071 if (machine ==
NULL) {
1072 ++session->
hists.stats.nr_unprocessable_samples;
1075 return tool->
sample(tool, event, sample, evsel, machine);
1077 return tool->
mmap(tool, event, sample, machine);
1079 return tool->
comm(tool, event, sample, machine);
1081 return tool->
fork(tool, event, sample, machine);
1083 return tool->
exit(tool, event, sample, machine);
1086 session->
hists.stats.total_lost +=
event->lost.lost;
1087 return tool->
lost(tool, event, sample, machine);
1089 return tool->
read(tool, event, sample, evsel, machine);
1091 return tool->
throttle(tool, event, sample, machine);
1093 return tool->
unthrottle(tool, event, sample, machine);
1095 ++session->
hists.stats.nr_unknown_events;
1100 static int perf_session__preprocess_sample(
struct perf_session *session,
1108 pr_debug(
"call-chain problem with event, skipping it.\n");
1109 ++session->
hists.stats.nr_invalid_chains;
1110 session->
hists.stats.total_invalid_chains += sample->
period;
1121 dump_event(session, event, file_offset,
NULL);
1124 switch (event->
header.type) {
1137 return tool->
build_id(tool, event, session);
1145 static void event_swap(
union perf_event *event,
bool sample_id_all)
1149 swap = perf_event__swap_ops[
event->header.type];
1151 swap(event, sample_id_all);
1154 static int perf_session__process_event(
struct perf_session *session,
1162 if (session->
header.needs_swap)
1171 return perf_session__process_user_event(session, event, tool, file_offset);
1181 if (perf_session__preprocess_sample(session, event, &sample))
1185 ret = perf_session_queue_event(session, event, &sample,
1191 return perf_session_deliver_event(session, event, &sample, tool,
1197 self->type = bswap_32(self->type);
1198 self->misc = bswap_16(self->misc);
1199 self->size = bswap_16(self->size);
1207 static struct thread *perf_session__register_idle_thread(
struct perf_session *
self)
1212 pr_err(
"problem inserting idle task.\n");
1219 static void perf_session__warn_about_errors(
const struct perf_session *session,
1224 ui__warning(
"Processed %d events and lost %d chunks!\n\n"
1225 "Check IO/CPU overload!\n\n",
1226 session->
hists.stats.nr_events[0],
1230 if (session->
hists.stats.nr_unknown_events != 0) {
1232 "Is this an older tool processing a perf.data "
1233 "file generated by a more recent tool?\n\n"
1234 "If that is not the case, consider "
1236 session->
hists.stats.nr_unknown_events);
1239 if (session->
hists.stats.nr_unknown_id != 0) {
1240 ui__warning(
"%u samples with id not present in the header\n",
1241 session->
hists.stats.nr_unknown_id);
1244 if (session->
hists.stats.nr_invalid_chains != 0) {
1246 "%u out of %u events were discarded for this reason.\n\n"
1248 session->
hists.stats.nr_invalid_chains,
1252 if (session->
hists.stats.nr_unprocessable_samples != 0) {
1253 ui__warning(
"%u unprocessable samples recorded.\n"
1254 "Do you have a KVM guest running and not using 'perf kvm'?\n",
1255 session->
hists.stats.nr_unprocessable_samples);
1259 #define session_done() (*(volatile int *)(&session_done))
1262 static int __perf_session__process_pipe_events(
struct perf_session *
self,
1273 perf_tool__fill_defaults(tool);
1288 pr_err(
"failed to read event header\n");
1292 if (self->header.needs_swap)
1295 size =
event->header.size;
1299 if (size > cur_size) {
1300 void *
new = realloc(buf, size);
1302 pr_err(
"failed to allocate memory to read event\n");
1316 pr_err(
"unexpected end of event stream\n");
1320 pr_err(
"failed to read event data\n");
1325 if ((skip = perf_session__process_event(
self, event, tool, head)) < 0) {
1326 pr_err(
"%#" PRIx64 " [%#x]: failed to process type: %d\n",
1343 perf_session__warn_about_errors(
self, tool);
1344 perf_session_free_sample_buffers(
self);
1350 u64 head,
size_t mmap_size,
char *
buf)
1358 if (head +
sizeof(event->
header) > mmap_size)
1363 if (session->
header.needs_swap)
1366 if (head + event->
header.size > mmap_size)
1377 int err, mmap_prot, mmap_flags, map_idx = 0;
1379 char *
buf, *mmaps[8];
1383 perf_tool__fill_defaults(tool);
1385 page_size = sysconf(_SC_PAGESIZE);
1387 page_offset = page_size * (data_offset /
page_size);
1391 if (data_offset + data_size < file_size)
1394 progress_next = file_size / 16;
1397 if (mmap_size > file_size)
1400 memset(mmaps, 0,
sizeof(mmaps));
1405 if (session->
header.needs_swap) {
1410 buf =
mmap(
NULL, mmap_size, mmap_prot, mmap_flags, session->
fd,
1412 if (buf == MAP_FAILED) {
1413 pr_err(
"failed to mmap file\n");
1417 mmaps[map_idx] =
buf;
1418 map_idx = (map_idx + 1) & (
ARRAY_SIZE(mmaps) - 1);
1419 file_pos = file_offset +
head;
1422 event = fetch_mmaped_event(session, head, mmap_size, buf);
1424 if (mmaps[map_idx]) {
1425 munmap(mmaps[map_idx], mmap_size);
1426 mmaps[map_idx] =
NULL;
1429 page_offset = page_size * (head /
page_size);
1435 size =
event->header.size;
1438 perf_session__process_event(session, event, tool, file_pos) < 0) {
1439 pr_err(
"%#" PRIx64 " [%#x]: failed to process type: %d\n",
1440 file_offset + head, event->
header.size,
1449 if (file_pos >= progress_next) {
1450 progress_next += file_size / 16;
1452 "Processing events...");
1455 if (file_pos < file_size)
1461 err = flush_sample_queue(session, tool);
1463 perf_session__warn_about_errors(session, tool);
1464 perf_session_free_sample_buffers(session);
1473 if (perf_session__register_idle_thread(
self) ==
NULL)
1478 self->header.data_offset,
1479 self->header.data_size,
1482 err = __perf_session__process_pipe_events(
self, tool);
1490 pr_err(
"No trace sample to read. Did you call 'perf %s'?\n", msg);
1498 const char *symbol_name,
u64 addr)
1508 ref->
name = strdup(symbol_name);
1521 struct kmap *
kmap = map__kmap(maps[i]);
1545 size_t ret =
fprintf(fp,
"Aggregated stats:\n");
1584 if (pos->
attr.type == type)
1591 struct perf_sample *sample,
struct machine *machine,
1592 int print_sym,
int print_dso,
int print_symoffset)
1599 error(
"problem processing %d event, skipping it.\n",
1608 sample,
NULL) != 0) {
1610 error(
"Failed to resolve callchain. Skipping\n");
1639 if (print_symoffset)
1655 const char *cpu_list,
unsigned long *cpu_bitmap)
1667 if (!(evsel->
attr.sample_type & PERF_SAMPLE_CPU)) {
1668 pr_err(
"File does not contain CPU events. "
1669 "Remove -c option to proceed.\n");
1676 pr_err(
"Invalid cpu_list\n");
1680 for (i = 0; i < map->
nr; i++) {
1684 pr_err(
"Requested CPU %d too large. "
1685 "Consider raising MAX_NR_CPUS\n", cpu);
1704 ret = fstat(session->
fd, &st);
1711 fprintf(fp,
"# ========\n#\n");
1726 for (i = 0; i < nr_assocs; i++) {
1728 tracepoint = strdup(assocs[i].name);
1729 if (tracepoint ==
NULL)
1733 name =
strchr(tracepoint,
':');
1740 if (format ==
NULL) {