1 #define _FILE_OFFSET_BITS 64 2 3 #include <linux/kernel.h> 4 5 #include <byteswap.h> 6 #include <unistd.h> 7 #include <sys/types.h> 8 #include <sys/mman.h> 9 10 #include "evlist.h" 11 #include "evsel.h" 12 #include "session.h" 13 #include "tool.h" 14 #include "sort.h" 15 #include "util.h" 16 #include "cpumap.h" 17 #include "event-parse.h" 18 #include "perf_regs.h" 19 #include "unwind.h" 20 #include "vdso.h" 21 22 static int perf_session__open(struct perf_session *self, bool force) 23 { 24 struct stat input_stat; 25 26 if (!strcmp(self->filename, "-")) { 27 self->fd_pipe = true; 28 self->fd = STDIN_FILENO; 29 30 if (perf_session__read_header(self, self->fd) < 0) 31 pr_err("incompatible file format (rerun with -v to learn more)"); 32 33 return 0; 34 } 35 36 self->fd = open(self->filename, O_RDONLY); 37 if (self->fd < 0) { 38 int err = errno; 39 40 pr_err("failed to open %s: %s", self->filename, strerror(err)); 41 if (err == ENOENT && !strcmp(self->filename, "perf.data")) 42 pr_err(" (try 'perf record' first)"); 43 pr_err("\n"); 44 return -errno; 45 } 46 47 if (fstat(self->fd, &input_stat) < 0) 48 goto out_close; 49 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", 52 self->filename); 53 goto out_close; 54 } 55 56 if (!input_stat.st_size) { 57 pr_info("zero-sized file (%s), nothing to do!\n", 58 self->filename); 59 goto out_close; 60 } 61 62 if (perf_session__read_header(self, self->fd) < 0) { 63 pr_err("incompatible file format (rerun with -v to learn more)"); 64 goto out_close; 65 } 66 67 if (!perf_evlist__valid_sample_type(self->evlist)) { 68 pr_err("non matching sample_type"); 69 goto out_close; 70 } 71 72 if (!perf_evlist__valid_sample_id_all(self->evlist)) { 73 pr_err("non matching sample_id_all"); 74 goto out_close; 75 } 76 77 self->size = input_stat.st_size; 78 return 0; 79 80 out_close: 81 close(self->fd); 82 self->fd = -1; 83 return -1; 84 } 85 86 void perf_session__set_id_hdr_size(struct perf_session *session) 87 { 88 u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist); 89 90 session->host_machine.id_hdr_size = id_hdr_size; 91 machines__set_id_hdr_size(&session->machines, id_hdr_size); 92 } 93 94 int perf_session__create_kernel_maps(struct perf_session *self) 95 { 96 int ret = machine__create_kernel_maps(&self->host_machine); 97 98 if (ret >= 0) 99 ret = machines__create_guest_kernel_maps(&self->machines); 100 return ret; 101 } 102 103 static void perf_session__destroy_kernel_maps(struct perf_session *self) 104 { 105 machine__destroy_kernel_maps(&self->host_machine); 106 machines__destroy_guest_kernel_maps(&self->machines); 107 } 108 109 struct perf_session *perf_session__new(const char *filename, int mode, 110 bool force, bool repipe, 111 struct perf_tool *tool) 112 { 113 struct perf_session *self; 114 struct stat st; 115 size_t len; 116 117 if (!filename || !strlen(filename)) { 118 if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode)) 119 filename = "-"; 120 else 121 filename = "perf.data"; 122 } 123 124 len = strlen(filename); 125 self = zalloc(sizeof(*self) + len); 126 127 if (self == NULL) 128 goto out; 129 130 memcpy(self->filename, filename, len); 131 /* 132 * On 64bit we can mmap the data file in one go. No need for tiny mmap 133 * slices. On 32bit we use 32MB. 134 */ 135 #if BITS_PER_LONG == 64 136 self->mmap_window = ULLONG_MAX; 137 #else 138 self->mmap_window = 32 * 1024 * 1024ULL; 139 #endif 140 self->machines = RB_ROOT; 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); 145 machine__init(&self->host_machine, "", HOST_KERNEL_ID); 146 hists__init(&self->hists); 147 148 if (mode == O_RDONLY) { 149 if (perf_session__open(self, force) < 0) 150 goto out_delete; 151 perf_session__set_id_hdr_size(self); 152 } else if (mode == O_WRONLY) { 153 /* 154 * In O_RDONLY mode this will be performed when reading the 155 * kernel MMAP event, in perf_event__process_mmap(). 156 */ 157 if (perf_session__create_kernel_maps(self) < 0) 158 goto out_delete; 159 } 160 161 if (tool && tool->ordering_requires_timestamps && 162 tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) { 163 dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); 164 tool->ordered_samples = false; 165 } 166 167 out: 168 return self; 169 out_delete: 170 perf_session__delete(self); 171 return NULL; 172 } 173 174 static void machine__delete_dead_threads(struct machine *machine) 175 { 176 struct thread *n, *t; 177 178 list_for_each_entry_safe(t, n, &machine->dead_threads, node) { 179 list_del(&t->node); 180 thread__delete(t); 181 } 182 } 183 184 static void perf_session__delete_dead_threads(struct perf_session *session) 185 { 186 machine__delete_dead_threads(&session->host_machine); 187 } 188 189 static void machine__delete_threads(struct machine *self) 190 { 191 struct rb_node *nd = rb_first(&self->threads); 192 193 while (nd) { 194 struct thread *t = rb_entry(nd, struct thread, rb_node); 195 196 rb_erase(&t->rb_node, &self->threads); 197 nd = rb_next(nd); 198 thread__delete(t); 199 } 200 } 201 202 static void perf_session__delete_threads(struct perf_session *session) 203 { 204 machine__delete_threads(&session->host_machine); 205 } 206 207 static void perf_session_env__delete(struct perf_session_env *env) 208 { 209 free(env->hostname); 210 free(env->os_release); 211 free(env->version); 212 free(env->arch); 213 free(env->cpu_desc); 214 free(env->cpuid); 215 216 free(env->cmdline); 217 free(env->sibling_cores); 218 free(env->sibling_threads); 219 free(env->numa_nodes); 220 free(env->pmu_mappings); 221 } 222 223 void perf_session__delete(struct perf_session *self) 224 { 225 perf_session__destroy_kernel_maps(self); 226 perf_session__delete_dead_threads(self); 227 perf_session__delete_threads(self); 228 perf_session_env__delete(&self->header.env); 229 machine__exit(&self->host_machine); 230 close(self->fd); 231 free(self); 232 vdso__exit(); 233 } 234 235 void machine__remove_thread(struct machine *self, struct thread *th) 236 { 237 self->last_match = NULL; 238 rb_erase(&th->rb_node, &self->threads); 239 /* 240 * We may have references to this thread, for instance in some hist_entry 241 * instances, so just move them to a separate list. 242 */ 243 list_add_tail(&th->node, &self->dead_threads); 244 } 245 246 static bool symbol__match_parent_regex(struct symbol *sym) 247 { 248 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0)) 249 return 1; 250 251 return 0; 252 } 253 254 static const u8 cpumodes[] = { 255 PERF_RECORD_MISC_USER, 256 PERF_RECORD_MISC_KERNEL, 257 PERF_RECORD_MISC_GUEST_USER, 258 PERF_RECORD_MISC_GUEST_KERNEL 259 }; 260 #define NCPUMODES (sizeof(cpumodes)/sizeof(u8)) 261 262 static void ip__resolve_ams(struct machine *self, struct thread *thread, 263 struct addr_map_symbol *ams, 264 u64 ip) 265 { 266 struct addr_location al; 267 size_t i; 268 u8 m; 269 270 memset(&al, 0, sizeof(al)); 271 272 for (i = 0; i < NCPUMODES; i++) { 273 m = cpumodes[i]; 274 /* 275 * We cannot use the header.misc hint to determine whether a 276 * branch stack address is user, kernel, guest, hypervisor. 277 * Branches may straddle the kernel/user/hypervisor boundaries. 278 * Thus, we have to try consecutively until we find a match 279 * or else, the symbol is unknown 280 */ 281 thread__find_addr_location(thread, self, m, MAP__FUNCTION, 282 ip, &al, NULL); 283 if (al.sym) 284 goto found; 285 } 286 found: 287 ams->addr = ip; 288 ams->al_addr = al.addr; 289 ams->sym = al.sym; 290 ams->map = al.map; 291 } 292 293 struct branch_info *machine__resolve_bstack(struct machine *self, 294 struct thread *thr, 295 struct branch_stack *bs) 296 { 297 struct branch_info *bi; 298 unsigned int i; 299 300 bi = calloc(bs->nr, sizeof(struct branch_info)); 301 if (!bi) 302 return NULL; 303 304 for (i = 0; i < bs->nr; i++) { 305 ip__resolve_ams(self, thr, &bi[i].to, bs->entries[i].to); 306 ip__resolve_ams(self, thr, &bi[i].from, bs->entries[i].from); 307 bi[i].flags = bs->entries[i].flags; 308 } 309 return bi; 310 } 311 312 static int machine__resolve_callchain_sample(struct machine *machine, 313 struct thread *thread, 314 struct ip_callchain *chain, 315 struct symbol **parent) 316 317 { 318 u8 cpumode = PERF_RECORD_MISC_USER; 319 unsigned int i; 320 int err; 321 322 callchain_cursor_reset(&callchain_cursor); 323 324 if (chain->nr > PERF_MAX_STACK_DEPTH) { 325 pr_warning("corrupted callchain. skipping...\n"); 326 return 0; 327 } 328 329 for (i = 0; i < chain->nr; i++) { 330 u64 ip; 331 struct addr_location al; 332 333 if (callchain_param.order == ORDER_CALLEE) 334 ip = chain->ips[i]; 335 else 336 ip = chain->ips[chain->nr - i - 1]; 337 338 if (ip >= PERF_CONTEXT_MAX) { 339 switch (ip) { 340 case PERF_CONTEXT_HV: 341 cpumode = PERF_RECORD_MISC_HYPERVISOR; 342 break; 343 case PERF_CONTEXT_KERNEL: 344 cpumode = PERF_RECORD_MISC_KERNEL; 345 break; 346 case PERF_CONTEXT_USER: 347 cpumode = PERF_RECORD_MISC_USER; 348 break; 349 default: 350 pr_debug("invalid callchain context: " 351 "%"PRId64"\n", (s64) ip); 352 /* 353 * It seems the callchain is corrupted. 354 * Discard all. 355 */ 356 callchain_cursor_reset(&callchain_cursor); 357 return 0; 358 } 359 continue; 360 } 361 362 al.filtered = false; 363 thread__find_addr_location(thread, machine, cpumode, 364 MAP__FUNCTION, ip, &al, NULL); 365 if (al.sym != NULL) { 366 if (sort__has_parent && !*parent && 367 symbol__match_parent_regex(al.sym)) 368 *parent = al.sym; 369 if (!symbol_conf.use_callchain) 370 break; 371 } 372 373 err = callchain_cursor_append(&callchain_cursor, 374 ip, al.map, al.sym); 375 if (err) 376 return err; 377 } 378 379 return 0; 380 } 381 382 static int unwind_entry(struct unwind_entry *entry, void *arg) 383 { 384 struct callchain_cursor *cursor = arg; 385 return callchain_cursor_append(cursor, entry->ip, 386 entry->map, entry->sym); 387 } 388 389 int machine__resolve_callchain(struct machine *machine, 390 struct perf_evsel *evsel, 391 struct thread *thread, 392 struct perf_sample *sample, 393 struct symbol **parent) 394 395 { 396 int ret; 397 398 callchain_cursor_reset(&callchain_cursor); 399 400 ret = machine__resolve_callchain_sample(machine, thread, 401 sample->callchain, parent); 402 if (ret) 403 return ret; 404 405 /* Can we do dwarf post unwind? */ 406 if (!((evsel->attr.sample_type & PERF_SAMPLE_REGS_USER) && 407 (evsel->attr.sample_type & PERF_SAMPLE_STACK_USER))) 408 return 0; 409 410 /* Bail out if nothing was captured. */ 411 if ((!sample->user_regs.regs) || 412 (!sample->user_stack.size)) 413 return 0; 414 415 return unwind__get_entries(unwind_entry, &callchain_cursor, machine, 416 thread, evsel->attr.sample_regs_user, 417 sample); 418 419 } 420 421 static int process_event_synth_tracing_data_stub(union perf_event *event 422 __maybe_unused, 423 struct perf_session *session 424 __maybe_unused) 425 { 426 dump_printf(": unhandled!\n"); 427 return 0; 428 } 429 430 static int process_event_synth_attr_stub(union perf_event *event __maybe_unused, 431 struct perf_evlist **pevlist 432 __maybe_unused) 433 { 434 dump_printf(": unhandled!\n"); 435 return 0; 436 } 437 438 static int process_event_sample_stub(struct perf_tool *tool __maybe_unused, 439 union perf_event *event __maybe_unused, 440 struct perf_sample *sample __maybe_unused, 441 struct perf_evsel *evsel __maybe_unused, 442 struct machine *machine __maybe_unused) 443 { 444 dump_printf(": unhandled!\n"); 445 return 0; 446 } 447 448 static int process_event_stub(struct perf_tool *tool __maybe_unused, 449 union perf_event *event __maybe_unused, 450 struct perf_sample *sample __maybe_unused, 451 struct machine *machine __maybe_unused) 452 { 453 dump_printf(": unhandled!\n"); 454 return 0; 455 } 456 457 static int process_finished_round_stub(struct perf_tool *tool __maybe_unused, 458 union perf_event *event __maybe_unused, 459 struct perf_session *perf_session 460 __maybe_unused) 461 { 462 dump_printf(": unhandled!\n"); 463 return 0; 464 } 465 466 static int process_event_type_stub(struct perf_tool *tool __maybe_unused, 467 union perf_event *event __maybe_unused) 468 { 469 dump_printf(": unhandled!\n"); 470 return 0; 471 } 472 473 static int process_finished_round(struct perf_tool *tool, 474 union perf_event *event, 475 struct perf_session *session); 476 477 static void perf_tool__fill_defaults(struct perf_tool *tool) 478 { 479 if (tool->sample == NULL) 480 tool->sample = process_event_sample_stub; 481 if (tool->mmap == NULL) 482 tool->mmap = process_event_stub; 483 if (tool->comm == NULL) 484 tool->comm = process_event_stub; 485 if (tool->fork == NULL) 486 tool->fork = process_event_stub; 487 if (tool->exit == NULL) 488 tool->exit = process_event_stub; 489 if (tool->lost == NULL) 490 tool->lost = perf_event__process_lost; 491 if (tool->read == NULL) 492 tool->read = process_event_sample_stub; 493 if (tool->throttle == NULL) 494 tool->throttle = process_event_stub; 495 if (tool->unthrottle == NULL) 496 tool->unthrottle = process_event_stub; 497 if (tool->attr == NULL) 498 tool->attr = process_event_synth_attr_stub; 499 if (tool->event_type == NULL) 500 tool->event_type = process_event_type_stub; 501 if (tool->tracing_data == NULL) 502 tool->tracing_data = process_event_synth_tracing_data_stub; 503 if (tool->build_id == NULL) 504 tool->build_id = process_finished_round_stub; 505 if (tool->finished_round == NULL) { 506 if (tool->ordered_samples) 507 tool->finished_round = process_finished_round; 508 else 509 tool->finished_round = process_finished_round_stub; 510 } 511 } 512 513 void mem_bswap_32(void *src, int byte_size) 514 { 515 u32 *m = src; 516 while (byte_size > 0) { 517 *m = bswap_32(*m); 518 byte_size -= sizeof(u32); 519 ++m; 520 } 521 } 522 523 void mem_bswap_64(void *src, int byte_size) 524 { 525 u64 *m = src; 526 527 while (byte_size > 0) { 528 *m = bswap_64(*m); 529 byte_size -= sizeof(u64); 530 ++m; 531 } 532 } 533 534 static void swap_sample_id_all(union perf_event *event, void *data) 535 { 536 void *end = (void *) event + event->header.size; 537 int size = end - data; 538 539 BUG_ON(size % sizeof(u64)); 540 mem_bswap_64(data, size); 541 } 542 543 static void perf_event__all64_swap(union perf_event *event, 544 bool sample_id_all __maybe_unused) 545 { 546 struct perf_event_header *hdr = &event->header; 547 mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr)); 548 } 549 550 static void perf_event__comm_swap(union perf_event *event, bool sample_id_all) 551 { 552 event->comm.pid = bswap_32(event->comm.pid); 553 event->comm.tid = bswap_32(event->comm.tid); 554 555 if (sample_id_all) { 556 void *data = &event->comm.comm; 557 558 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64)); 559 swap_sample_id_all(event, data); 560 } 561 } 562 563 static void perf_event__mmap_swap(union perf_event *event, 564 bool sample_id_all) 565 { 566 event->mmap.pid = bswap_32(event->mmap.pid); 567 event->mmap.tid = bswap_32(event->mmap.tid); 568 event->mmap.start = bswap_64(event->mmap.start); 569 event->mmap.len = bswap_64(event->mmap.len); 570 event->mmap.pgoff = bswap_64(event->mmap.pgoff); 571 572 if (sample_id_all) { 573 void *data = &event->mmap.filename; 574 575 data += PERF_ALIGN(strlen(data) + 1, sizeof(u64)); 576 swap_sample_id_all(event, data); 577 } 578 } 579 580 static void perf_event__task_swap(union perf_event *event, bool sample_id_all) 581 { 582 event->fork.pid = bswap_32(event->fork.pid); 583 event->fork.tid = bswap_32(event->fork.tid); 584 event->fork.ppid = bswap_32(event->fork.ppid); 585 event->fork.ptid = bswap_32(event->fork.ptid); 586 event->fork.time = bswap_64(event->fork.time); 587 588 if (sample_id_all) 589 swap_sample_id_all(event, &event->fork + 1); 590 } 591 592 static void perf_event__read_swap(union perf_event *event, bool sample_id_all) 593 { 594 event->read.pid = bswap_32(event->read.pid); 595 event->read.tid = bswap_32(event->read.tid); 596 event->read.value = bswap_64(event->read.value); 597 event->read.time_enabled = bswap_64(event->read.time_enabled); 598 event->read.time_running = bswap_64(event->read.time_running); 599 event->read.id = bswap_64(event->read.id); 600 601 if (sample_id_all) 602 swap_sample_id_all(event, &event->read + 1); 603 } 604 605 static u8 revbyte(u8 b) 606 { 607 int rev = (b >> 4) | ((b & 0xf) << 4); 608 rev = ((rev & 0xcc) >> 2) | ((rev & 0x33) << 2); 609 rev = ((rev & 0xaa) >> 1) | ((rev & 0x55) << 1); 610 return (u8) rev; 611 } 612 613 /* 614 * XXX this is hack in attempt to carry flags bitfield 615 * throught endian village. ABI says: 616 * 617 * Bit-fields are allocated from right to left (least to most significant) 618 * on little-endian implementations and from left to right (most to least 619 * significant) on big-endian implementations. 620 * 621 * The above seems to be byte specific, so we need to reverse each 622 * byte of the bitfield. 'Internet' also says this might be implementation 623 * specific and we probably need proper fix and carry perf_event_attr 624 * bitfield flags in separate data file FEAT_ section. Thought this seems 625 * to work for now. 626 */ 627 static void swap_bitfield(u8 *p, unsigned len) 628 { 629 unsigned i; 630 631 for (i = 0; i < len; i++) { 632 *p = revbyte(*p); 633 p++; 634 } 635 } 636 637 /* exported for swapping attributes in file header */ 638 void perf_event__attr_swap(struct perf_event_attr *attr) 639 { 640 attr->type = bswap_32(attr->type); 641 attr->size = bswap_32(attr->size); 642 attr->config = bswap_64(attr->config); 643 attr->sample_period = bswap_64(attr->sample_period); 644 attr->sample_type = bswap_64(attr->sample_type); 645 attr->read_format = bswap_64(attr->read_format); 646 attr->wakeup_events = bswap_32(attr->wakeup_events); 647 attr->bp_type = bswap_32(attr->bp_type); 648 attr->bp_addr = bswap_64(attr->bp_addr); 649 attr->bp_len = bswap_64(attr->bp_len); 650 651 swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64)); 652 } 653 654 static void perf_event__hdr_attr_swap(union perf_event *event, 655 bool sample_id_all __maybe_unused) 656 { 657 size_t size; 658 659 perf_event__attr_swap(&event->attr.attr); 660 661 size = event->header.size; 662 size -= (void *)&event->attr.id - (void *)event; 663 mem_bswap_64(event->attr.id, size); 664 } 665 666 static void perf_event__event_type_swap(union perf_event *event, 667 bool sample_id_all __maybe_unused) 668 { 669 event->event_type.event_type.event_id = 670 bswap_64(event->event_type.event_type.event_id); 671 } 672 673 static void perf_event__tracing_data_swap(union perf_event *event, 674 bool sample_id_all __maybe_unused) 675 { 676 event->tracing_data.size = bswap_32(event->tracing_data.size); 677 } 678 679 typedef void (*perf_event__swap_op)(union perf_event *event, 680 bool sample_id_all); 681 682 static perf_event__swap_op perf_event__swap_ops[] = { 683 [PERF_RECORD_MMAP] = perf_event__mmap_swap, 684 [PERF_RECORD_COMM] = perf_event__comm_swap, 685 [PERF_RECORD_FORK] = perf_event__task_swap, 686 [PERF_RECORD_EXIT] = perf_event__task_swap, 687 [PERF_RECORD_LOST] = perf_event__all64_swap, 688 [PERF_RECORD_READ] = perf_event__read_swap, 689 [PERF_RECORD_SAMPLE] = perf_event__all64_swap, 690 [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap, 691 [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, 692 [PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap, 693 [PERF_RECORD_HEADER_BUILD_ID] = NULL, 694 [PERF_RECORD_HEADER_MAX] = NULL, 695 }; 696 697 struct sample_queue { 698 u64 timestamp; 699 u64 file_offset; 700 union perf_event *event; 701 struct list_head list; 702 }; 703 704 static void perf_session_free_sample_buffers(struct perf_session *session) 705 { 706 struct ordered_samples *os = &session->ordered_samples; 707 708 while (!list_empty(&os->to_free)) { 709 struct sample_queue *sq; 710 711 sq = list_entry(os->to_free.next, struct sample_queue, list); 712 list_del(&sq->list); 713 free(sq); 714 } 715 } 716 717 static int perf_session_deliver_event(struct perf_session *session, 718 union perf_event *event, 719 struct perf_sample *sample, 720 struct perf_tool *tool, 721 u64 file_offset); 722 723 static int flush_sample_queue(struct perf_session *s, 724 struct perf_tool *tool) 725 { 726 struct ordered_samples *os = &s->ordered_samples; 727 struct list_head *head = &os->samples; 728 struct sample_queue *tmp, *iter; 729 struct perf_sample sample; 730 u64 limit = os->next_flush; 731 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; 732 unsigned idx = 0, progress_next = os->nr_samples / 16; 733 int ret; 734 735 if (!tool->ordered_samples || !limit) 736 return 0; 737 738 list_for_each_entry_safe(iter, tmp, head, list) { 739 if (iter->timestamp > limit) 740 break; 741 742 ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample); 743 if (ret) 744 pr_err("Can't parse sample, err = %d\n", ret); 745 else { 746 ret = perf_session_deliver_event(s, iter->event, &sample, tool, 747 iter->file_offset); 748 if (ret) 749 return ret; 750 } 751 752 os->last_flush = iter->timestamp; 753 list_del(&iter->list); 754 list_add(&iter->list, &os->sample_cache); 755 if (++idx >= progress_next) { 756 progress_next += os->nr_samples / 16; 757 ui_progress__update(idx, os->nr_samples, 758 "Processing time ordered events..."); 759 } 760 } 761 762 if (list_empty(head)) { 763 os->last_sample = NULL; 764 } else if (last_ts <= limit) { 765 os->last_sample = 766 list_entry(head->prev, struct sample_queue, list); 767 } 768 769 os->nr_samples = 0; 770 771 return 0; 772 } 773 774 /* 775 * When perf record finishes a pass on every buffers, it records this pseudo 776 * event. 777 * We record the max timestamp t found in the pass n. 778 * Assuming these timestamps are monotonic across cpus, we know that if 779 * a buffer still has events with timestamps below t, they will be all 780 * available and then read in the pass n + 1. 781 * Hence when we start to read the pass n + 2, we can safely flush every 782 * events with timestamps below t. 783 * 784 * ============ PASS n ================= 785 * CPU 0 | CPU 1 786 * | 787 * cnt1 timestamps | cnt2 timestamps 788 * 1 | 2 789 * 2 | 3 790 * - | 4 <--- max recorded 791 * 792 * ============ PASS n + 1 ============== 793 * CPU 0 | CPU 1 794 * | 795 * cnt1 timestamps | cnt2 timestamps 796 * 3 | 5 797 * 4 | 6 798 * 5 | 7 <---- max recorded 799 * 800 * Flush every events below timestamp 4 801 * 802 * ============ PASS n + 2 ============== 803 * CPU 0 | CPU 1 804 * | 805 * cnt1 timestamps | cnt2 timestamps 806 * 6 | 8 807 * 7 | 9 808 * - | 10 809 * 810 * Flush every events below timestamp 7 811 * etc... 812 */ 813 static int process_finished_round(struct perf_tool *tool, 814 union perf_event *event __maybe_unused, 815 struct perf_session *session) 816 { 817 int ret = flush_sample_queue(session, tool); 818 if (!ret) 819 session->ordered_samples.next_flush = session->ordered_samples.max_timestamp; 820 821 return ret; 822 } 823 824 /* The queue is ordered by time */ 825 static void __queue_event(struct sample_queue *new, struct perf_session *s) 826 { 827 struct ordered_samples *os = &s->ordered_samples; 828 struct sample_queue *sample = os->last_sample; 829 u64 timestamp = new->timestamp; 830 struct list_head *p; 831 832 ++os->nr_samples; 833 os->last_sample = new; 834 835 if (!sample) { 836 list_add(&new->list, &os->samples); 837 os->max_timestamp = timestamp; 838 return; 839 } 840 841 /* 842 * last_sample might point to some random place in the list as it's 843 * the last queued event. We expect that the new event is close to 844 * this. 845 */ 846 if (sample->timestamp <= timestamp) { 847 while (sample->timestamp <= timestamp) { 848 p = sample->list.next; 849 if (p == &os->samples) { 850 list_add_tail(&new->list, &os->samples); 851 os->max_timestamp = timestamp; 852 return; 853 } 854 sample = list_entry(p, struct sample_queue, list); 855 } 856 list_add_tail(&new->list, &sample->list); 857 } else { 858 while (sample->timestamp > timestamp) { 859 p = sample->list.prev; 860 if (p == &os->samples) { 861 list_add(&new->list, &os->samples); 862 return; 863 } 864 sample = list_entry(p, struct sample_queue, list); 865 } 866 list_add(&new->list, &sample->list); 867 } 868 } 869 870 #define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue)) 871 872 static int perf_session_queue_event(struct perf_session *s, union perf_event *event, 873 struct perf_sample *sample, u64 file_offset) 874 { 875 struct ordered_samples *os = &s->ordered_samples; 876 struct list_head *sc = &os->sample_cache; 877 u64 timestamp = sample->time; 878 struct sample_queue *new; 879 880 if (!timestamp || timestamp == ~0ULL) 881 return -ETIME; 882 883 if (timestamp < s->ordered_samples.last_flush) { 884 printf("Warning: Timestamp below last timeslice flush\n"); 885 return -EINVAL; 886 } 887 888 if (!list_empty(sc)) { 889 new = list_entry(sc->next, struct sample_queue, list); 890 list_del(&new->list); 891 } else if (os->sample_buffer) { 892 new = os->sample_buffer + os->sample_buffer_idx; 893 if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER) 894 os->sample_buffer = NULL; 895 } else { 896 os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); 897 if (!os->sample_buffer) 898 return -ENOMEM; 899 list_add(&os->sample_buffer->list, &os->to_free); 900 os->sample_buffer_idx = 2; 901 new = os->sample_buffer + 1; 902 } 903 904 new->timestamp = timestamp; 905 new->file_offset = file_offset; 906 new->event = event; 907 908 __queue_event(new, s); 909 910 return 0; 911 } 912 913 static void callchain__printf(struct perf_sample *sample) 914 { 915 unsigned int i; 916 917 printf("... chain: nr:%" PRIu64 "\n", sample->callchain->nr); 918 919 for (i = 0; i < sample->callchain->nr; i++) 920 printf("..... %2d: %016" PRIx64 "\n", 921 i, sample->callchain->ips[i]); 922 } 923 924 static void branch_stack__printf(struct perf_sample *sample) 925 { 926 uint64_t i; 927 928 printf("... branch stack: nr:%" PRIu64 "\n", sample->branch_stack->nr); 929 930 for (i = 0; i < sample->branch_stack->nr; i++) 931 printf("..... %2"PRIu64": %016" PRIx64 " -> %016" PRIx64 "\n", 932 i, sample->branch_stack->entries[i].from, 933 sample->branch_stack->entries[i].to); 934 } 935 936 static void regs_dump__printf(u64 mask, u64 *regs) 937 { 938 unsigned rid, i = 0; 939 940 for_each_set_bit(rid, (unsigned long *) &mask, sizeof(mask) * 8) { 941 u64 val = regs[i++]; 942 943 printf(".... %-5s 0x%" PRIx64 "\n", 944 perf_reg_name(rid), val); 945 } 946 } 947 948 static void regs_user__printf(struct perf_sample *sample, u64 mask) 949 { 950 struct regs_dump *user_regs = &sample->user_regs; 951 952 if (user_regs->regs) { 953 printf("... user regs: mask 0x%" PRIx64 "\n", mask); 954 regs_dump__printf(mask, user_regs->regs); 955 } 956 } 957 958 static void stack_user__printf(struct stack_dump *dump) 959 { 960 printf("... ustack: size %" PRIu64 ", offset 0x%x\n", 961 dump->size, dump->offset); 962 } 963 964 static void perf_session__print_tstamp(struct perf_session *session, 965 union perf_event *event, 966 struct perf_sample *sample) 967 { 968 u64 sample_type = perf_evlist__sample_type(session->evlist); 969 970 if (event->header.type != PERF_RECORD_SAMPLE && 971 !perf_evlist__sample_id_all(session->evlist)) { 972 fputs("-1 -1 ", stdout); 973 return; 974 } 975 976 if ((sample_type & PERF_SAMPLE_CPU)) 977 printf("%u ", sample->cpu); 978 979 if (sample_type & PERF_SAMPLE_TIME) 980 printf("%" PRIu64 " ", sample->time); 981 } 982 983 static void dump_event(struct perf_session *session, union perf_event *event, 984 u64 file_offset, struct perf_sample *sample) 985 { 986 if (!dump_trace) 987 return; 988 989 printf("\n%#" PRIx64 " [%#x]: event: %d\n", 990 file_offset, event->header.size, event->header.type); 991 992 trace_event(event); 993 994 if (sample) 995 perf_session__print_tstamp(session, event, sample); 996 997 printf("%#" PRIx64 " [%#x]: PERF_RECORD_%s", file_offset, 998 event->header.size, perf_event__name(event->header.type)); 999 } 1000 1001 static void dump_sample(struct perf_evsel *evsel, union perf_event *event, 1002 struct perf_sample *sample) 1003 { 1004 u64 sample_type; 1005 1006 if (!dump_trace) 1007 return; 1008 1009 printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n", 1010 event->header.misc, sample->pid, sample->tid, sample->ip, 1011 sample->period, sample->addr); 1012 1013 sample_type = evsel->attr.sample_type; 1014 1015 if (sample_type & PERF_SAMPLE_CALLCHAIN) 1016 callchain__printf(sample); 1017 1018 if (sample_type & PERF_SAMPLE_BRANCH_STACK) 1019 branch_stack__printf(sample); 1020 1021 if (sample_type & PERF_SAMPLE_REGS_USER) 1022 regs_user__printf(sample, evsel->attr.sample_regs_user); 1023 1024 if (sample_type & PERF_SAMPLE_STACK_USER) 1025 stack_user__printf(&sample->user_stack); 1026 } 1027 1028 static struct machine * 1029 perf_session__find_machine_for_cpumode(struct perf_session *session, 1030 union perf_event *event) 1031 { 1032 const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1033 1034 if (perf_guest && 1035 ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || 1036 (cpumode == PERF_RECORD_MISC_GUEST_USER))) { 1037 u32 pid; 1038 1039 if (event->header.type == PERF_RECORD_MMAP) 1040 pid = event->mmap.pid; 1041 else 1042 pid = event->ip.pid; 1043 1044 return perf_session__findnew_machine(session, pid); 1045 } 1046 1047 return perf_session__find_host_machine(session); 1048 } 1049 1050 static int perf_session_deliver_event(struct perf_session *session, 1051 union perf_event *event, 1052 struct perf_sample *sample, 1053 struct perf_tool *tool, 1054 u64 file_offset) 1055 { 1056 struct perf_evsel *evsel; 1057 struct machine *machine; 1058 1059 dump_event(session, event, file_offset, sample); 1060 1061 evsel = perf_evlist__id2evsel(session->evlist, sample->id); 1062 if (evsel != NULL && event->header.type != PERF_RECORD_SAMPLE) { 1063 /* 1064 * XXX We're leaving PERF_RECORD_SAMPLE unnacounted here 1065 * because the tools right now may apply filters, discarding 1066 * some of the samples. For consistency, in the future we 1067 * should have something like nr_filtered_samples and remove 1068 * the sample->period from total_sample_period, etc, KISS for 1069 * now tho. 1070 * 1071 * Also testing against NULL allows us to handle files without 1072 * attr.sample_id_all and/or without PERF_SAMPLE_ID. In the 1073 * future probably it'll be a good idea to restrict event 1074 * processing via perf_session to files with both set. 1075 */ 1076 hists__inc_nr_events(&evsel->hists, event->header.type); 1077 } 1078 1079 machine = perf_session__find_machine_for_cpumode(session, event); 1080 1081 switch (event->header.type) { 1082 case PERF_RECORD_SAMPLE: 1083 dump_sample(evsel, event, sample); 1084 if (evsel == NULL) { 1085 ++session->hists.stats.nr_unknown_id; 1086 return 0; 1087 } 1088 if (machine == NULL) { 1089 ++session->hists.stats.nr_unprocessable_samples; 1090 return 0; 1091 } 1092 return tool->sample(tool, event, sample, evsel, machine); 1093 case PERF_RECORD_MMAP: 1094 return tool->mmap(tool, event, sample, machine); 1095 case PERF_RECORD_COMM: 1096 return tool->comm(tool, event, sample, machine); 1097 case PERF_RECORD_FORK: 1098 return tool->fork(tool, event, sample, machine); 1099 case PERF_RECORD_EXIT: 1100 return tool->exit(tool, event, sample, machine); 1101 case PERF_RECORD_LOST: 1102 if (tool->lost == perf_event__process_lost) 1103 session->hists.stats.total_lost += event->lost.lost; 1104 return tool->lost(tool, event, sample, machine); 1105 case PERF_RECORD_READ: 1106 return tool->read(tool, event, sample, evsel, machine); 1107 case PERF_RECORD_THROTTLE: 1108 return tool->throttle(tool, event, sample, machine); 1109 case PERF_RECORD_UNTHROTTLE: 1110 return tool->unthrottle(tool, event, sample, machine); 1111 default: 1112 ++session->hists.stats.nr_unknown_events; 1113 return -1; 1114 } 1115 } 1116 1117 static int perf_session__preprocess_sample(struct perf_session *session, 1118 union perf_event *event, struct perf_sample *sample) 1119 { 1120 if (event->header.type != PERF_RECORD_SAMPLE || 1121 !(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_CALLCHAIN)) 1122 return 0; 1123 1124 if (!ip_callchain__valid(sample->callchain, event)) { 1125 pr_debug("call-chain problem with event, skipping it.\n"); 1126 ++session->hists.stats.nr_invalid_chains; 1127 session->hists.stats.total_invalid_chains += sample->period; 1128 return -EINVAL; 1129 } 1130 return 0; 1131 } 1132 1133 static int perf_session__process_user_event(struct perf_session *session, union perf_event *event, 1134 struct perf_tool *tool, u64 file_offset) 1135 { 1136 int err; 1137 1138 dump_event(session, event, file_offset, NULL); 1139 1140 /* These events are processed right away */ 1141 switch (event->header.type) { 1142 case PERF_RECORD_HEADER_ATTR: 1143 err = tool->attr(event, &session->evlist); 1144 if (err == 0) 1145 perf_session__set_id_hdr_size(session); 1146 return err; 1147 case PERF_RECORD_HEADER_EVENT_TYPE: 1148 return tool->event_type(tool, event); 1149 case PERF_RECORD_HEADER_TRACING_DATA: 1150 /* setup for reading amidst mmap */ 1151 lseek(session->fd, file_offset, SEEK_SET); 1152 return tool->tracing_data(event, session); 1153 case PERF_RECORD_HEADER_BUILD_ID: 1154 return tool->build_id(tool, event, session); 1155 case PERF_RECORD_FINISHED_ROUND: 1156 return tool->finished_round(tool, event, session); 1157 default: 1158 return -EINVAL; 1159 } 1160 } 1161 1162 static void event_swap(union perf_event *event, bool sample_id_all) 1163 { 1164 perf_event__swap_op swap; 1165 1166 swap = perf_event__swap_ops[event->header.type]; 1167 if (swap) 1168 swap(event, sample_id_all); 1169 } 1170 1171 static int perf_session__process_event(struct perf_session *session, 1172 union perf_event *event, 1173 struct perf_tool *tool, 1174 u64 file_offset) 1175 { 1176 struct perf_sample sample; 1177 int ret; 1178 1179 if (session->header.needs_swap) 1180 event_swap(event, perf_evlist__sample_id_all(session->evlist)); 1181 1182 if (event->header.type >= PERF_RECORD_HEADER_MAX) 1183 return -EINVAL; 1184 1185 hists__inc_nr_events(&session->hists, event->header.type); 1186 1187 if (event->header.type >= PERF_RECORD_USER_TYPE_START) 1188 return perf_session__process_user_event(session, event, tool, file_offset); 1189 1190 /* 1191 * For all kernel events we get the sample data 1192 */ 1193 ret = perf_evlist__parse_sample(session->evlist, event, &sample); 1194 if (ret) 1195 return ret; 1196 1197 /* Preprocess sample records - precheck callchains */ 1198 if (perf_session__preprocess_sample(session, event, &sample)) 1199 return 0; 1200 1201 if (tool->ordered_samples) { 1202 ret = perf_session_queue_event(session, event, &sample, 1203 file_offset); 1204 if (ret != -ETIME) 1205 return ret; 1206 } 1207 1208 return perf_session_deliver_event(session, event, &sample, tool, 1209 file_offset); 1210 } 1211 1212 void perf_event_header__bswap(struct perf_event_header *self) 1213 { 1214 self->type = bswap_32(self->type); 1215 self->misc = bswap_16(self->misc); 1216 self->size = bswap_16(self->size); 1217 } 1218 1219 struct thread *perf_session__findnew(struct perf_session *session, pid_t pid) 1220 { 1221 return machine__findnew_thread(&session->host_machine, pid); 1222 } 1223 1224 static struct thread *perf_session__register_idle_thread(struct perf_session *self) 1225 { 1226 struct thread *thread = perf_session__findnew(self, 0); 1227 1228 if (thread == NULL || thread__set_comm(thread, "swapper")) { 1229 pr_err("problem inserting idle task.\n"); 1230 thread = NULL; 1231 } 1232 1233 return thread; 1234 } 1235 1236 static void perf_session__warn_about_errors(const struct perf_session *session, 1237 const struct perf_tool *tool) 1238 { 1239 if (tool->lost == perf_event__process_lost && 1240 session->hists.stats.nr_events[PERF_RECORD_LOST] != 0) { 1241 ui__warning("Processed %d events and lost %d chunks!\n\n" 1242 "Check IO/CPU overload!\n\n", 1243 session->hists.stats.nr_events[0], 1244 session->hists.stats.nr_events[PERF_RECORD_LOST]); 1245 } 1246 1247 if (session->hists.stats.nr_unknown_events != 0) { 1248 ui__warning("Found %u unknown events!\n\n" 1249 "Is this an older tool processing a perf.data " 1250 "file generated by a more recent tool?\n\n" 1251 "If that is not the case, consider " 1252 "reporting to linux-kernel@vger.kernel.org.\n\n", 1253 session->hists.stats.nr_unknown_events); 1254 } 1255 1256 if (session->hists.stats.nr_unknown_id != 0) { 1257 ui__warning("%u samples with id not present in the header\n", 1258 session->hists.stats.nr_unknown_id); 1259 } 1260 1261 if (session->hists.stats.nr_invalid_chains != 0) { 1262 ui__warning("Found invalid callchains!\n\n" 1263 "%u out of %u events were discarded for this reason.\n\n" 1264 "Consider reporting to linux-kernel@vger.kernel.org.\n\n", 1265 session->hists.stats.nr_invalid_chains, 1266 session->hists.stats.nr_events[PERF_RECORD_SAMPLE]); 1267 } 1268 1269 if (session->hists.stats.nr_unprocessable_samples != 0) { 1270 ui__warning("%u unprocessable samples recorded.\n" 1271 "Do you have a KVM guest running and not using 'perf kvm'?\n", 1272 session->hists.stats.nr_unprocessable_samples); 1273 } 1274 } 1275 1276 #define session_done() (*(volatile int *)(&session_done)) 1277 volatile int session_done; 1278 1279 static int __perf_session__process_pipe_events(struct perf_session *self, 1280 struct perf_tool *tool) 1281 { 1282 union perf_event *event; 1283 uint32_t size, cur_size = 0; 1284 void *buf = NULL; 1285 int skip = 0; 1286 u64 head; 1287 int err; 1288 void *p; 1289 1290 perf_tool__fill_defaults(tool); 1291 1292 head = 0; 1293 cur_size = sizeof(union perf_event); 1294 1295 buf = malloc(cur_size); 1296 if (!buf) 1297 return -errno; 1298 more: 1299 event = buf; 1300 err = readn(self->fd, event, sizeof(struct perf_event_header)); 1301 if (err <= 0) { 1302 if (err == 0) 1303 goto done; 1304 1305 pr_err("failed to read event header\n"); 1306 goto out_err; 1307 } 1308 1309 if (self->header.needs_swap) 1310 perf_event_header__bswap(&event->header); 1311 1312 size = event->header.size; 1313 if (size == 0) 1314 size = 8; 1315 1316 if (size > cur_size) { 1317 void *new = realloc(buf, size); 1318 if (!new) { 1319 pr_err("failed to allocate memory to read event\n"); 1320 goto out_err; 1321 } 1322 buf = new; 1323 cur_size = size; 1324 event = buf; 1325 } 1326 p = event; 1327 p += sizeof(struct perf_event_header); 1328 1329 if (size - sizeof(struct perf_event_header)) { 1330 err = readn(self->fd, p, size - sizeof(struct perf_event_header)); 1331 if (err <= 0) { 1332 if (err == 0) { 1333 pr_err("unexpected end of event stream\n"); 1334 goto done; 1335 } 1336 1337 pr_err("failed to read event data\n"); 1338 goto out_err; 1339 } 1340 } 1341 1342 if ((skip = perf_session__process_event(self, event, tool, head)) < 0) { 1343 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", 1344 head, event->header.size, event->header.type); 1345 err = -EINVAL; 1346 goto out_err; 1347 } 1348 1349 head += size; 1350 1351 if (skip > 0) 1352 head += skip; 1353 1354 if (!session_done()) 1355 goto more; 1356 done: 1357 err = 0; 1358 out_err: 1359 free(buf); 1360 perf_session__warn_about_errors(self, tool); 1361 perf_session_free_sample_buffers(self); 1362 return err; 1363 } 1364 1365 static union perf_event * 1366 fetch_mmaped_event(struct perf_session *session, 1367 u64 head, size_t mmap_size, char *buf) 1368 { 1369 union perf_event *event; 1370 1371 /* 1372 * Ensure we have enough space remaining to read 1373 * the size of the event in the headers. 1374 */ 1375 if (head + sizeof(event->header) > mmap_size) 1376 return NULL; 1377 1378 event = (union perf_event *)(buf + head); 1379 1380 if (session->header.needs_swap) 1381 perf_event_header__bswap(&event->header); 1382 1383 if (head + event->header.size > mmap_size) 1384 return NULL; 1385 1386 return event; 1387 } 1388 1389 int __perf_session__process_events(struct perf_session *session, 1390 u64 data_offset, u64 data_size, 1391 u64 file_size, struct perf_tool *tool) 1392 { 1393 u64 head, page_offset, file_offset, file_pos, progress_next; 1394 int err, mmap_prot, mmap_flags, map_idx = 0; 1395 size_t mmap_size; 1396 char *buf, *mmaps[8]; 1397 union perf_event *event; 1398 uint32_t size; 1399 1400 perf_tool__fill_defaults(tool); 1401 1402 page_offset = page_size * (data_offset / page_size); 1403 file_offset = page_offset; 1404 head = data_offset - page_offset; 1405 1406 if (data_offset + data_size < file_size) 1407 file_size = data_offset + data_size; 1408 1409 progress_next = file_size / 16; 1410 1411 mmap_size = session->mmap_window; 1412 if (mmap_size > file_size) 1413 mmap_size = file_size; 1414 1415 memset(mmaps, 0, sizeof(mmaps)); 1416 1417 mmap_prot = PROT_READ; 1418 mmap_flags = MAP_SHARED; 1419 1420 if (session->header.needs_swap) { 1421 mmap_prot |= PROT_WRITE; 1422 mmap_flags = MAP_PRIVATE; 1423 } 1424 remap: 1425 buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, session->fd, 1426 file_offset); 1427 if (buf == MAP_FAILED) { 1428 pr_err("failed to mmap file\n"); 1429 err = -errno; 1430 goto out_err; 1431 } 1432 mmaps[map_idx] = buf; 1433 map_idx = (map_idx + 1) & (ARRAY_SIZE(mmaps) - 1); 1434 file_pos = file_offset + head; 1435 1436 more: 1437 event = fetch_mmaped_event(session, head, mmap_size, buf); 1438 if (!event) { 1439 if (mmaps[map_idx]) { 1440 munmap(mmaps[map_idx], mmap_size); 1441 mmaps[map_idx] = NULL; 1442 } 1443 1444 page_offset = page_size * (head / page_size); 1445 file_offset += page_offset; 1446 head -= page_offset; 1447 goto remap; 1448 } 1449 1450 size = event->header.size; 1451 1452 if (size == 0 || 1453 perf_session__process_event(session, event, tool, file_pos) < 0) { 1454 pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", 1455 file_offset + head, event->header.size, 1456 event->header.type); 1457 err = -EINVAL; 1458 goto out_err; 1459 } 1460 1461 head += size; 1462 file_pos += size; 1463 1464 if (file_pos >= progress_next) { 1465 progress_next += file_size / 16; 1466 ui_progress__update(file_pos, file_size, 1467 "Processing events..."); 1468 } 1469 1470 if (file_pos < file_size) 1471 goto more; 1472 1473 err = 0; 1474 /* do the final flush for ordered samples */ 1475 session->ordered_samples.next_flush = ULLONG_MAX; 1476 err = flush_sample_queue(session, tool); 1477 out_err: 1478 ui_progress__finish(); 1479 perf_session__warn_about_errors(session, tool); 1480 perf_session_free_sample_buffers(session); 1481 return err; 1482 } 1483 1484 int perf_session__process_events(struct perf_session *self, 1485 struct perf_tool *tool) 1486 { 1487 int err; 1488 1489 if (perf_session__register_idle_thread(self) == NULL) 1490 return -ENOMEM; 1491 1492 if (!self->fd_pipe) 1493 err = __perf_session__process_events(self, 1494 self->header.data_offset, 1495 self->header.data_size, 1496 self->size, tool); 1497 else 1498 err = __perf_session__process_pipe_events(self, tool); 1499 1500 return err; 1501 } 1502 1503 bool perf_session__has_traces(struct perf_session *session, const char *msg) 1504 { 1505 if (!(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_RAW)) { 1506 pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); 1507 return false; 1508 } 1509 1510 return true; 1511 } 1512 1513 int maps__set_kallsyms_ref_reloc_sym(struct map **maps, 1514 const char *symbol_name, u64 addr) 1515 { 1516 char *bracket; 1517 enum map_type i; 1518 struct ref_reloc_sym *ref; 1519 1520 ref = zalloc(sizeof(struct ref_reloc_sym)); 1521 if (ref == NULL) 1522 return -ENOMEM; 1523 1524 ref->name = strdup(symbol_name); 1525 if (ref->name == NULL) { 1526 free(ref); 1527 return -ENOMEM; 1528 } 1529 1530 bracket = strchr(ref->name, ']'); 1531 if (bracket) 1532 *bracket = '\0'; 1533 1534 ref->addr = addr; 1535 1536 for (i = 0; i < MAP__NR_TYPES; ++i) { 1537 struct kmap *kmap = map__kmap(maps[i]); 1538 kmap->ref_reloc_sym = ref; 1539 } 1540 1541 return 0; 1542 } 1543 1544 size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp) 1545 { 1546 return __dsos__fprintf(&self->host_machine.kernel_dsos, fp) + 1547 __dsos__fprintf(&self->host_machine.user_dsos, fp) + 1548 machines__fprintf_dsos(&self->machines, fp); 1549 } 1550 1551 size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp, 1552 bool with_hits) 1553 { 1554 size_t ret = machine__fprintf_dsos_buildid(&self->host_machine, fp, with_hits); 1555 return ret + machines__fprintf_dsos_buildid(&self->machines, fp, with_hits); 1556 } 1557 1558 size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) 1559 { 1560 struct perf_evsel *pos; 1561 size_t ret = fprintf(fp, "Aggregated stats:\n"); 1562 1563 ret += hists__fprintf_nr_events(&session->hists, fp); 1564 1565 list_for_each_entry(pos, &session->evlist->entries, node) { 1566 ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); 1567 ret += hists__fprintf_nr_events(&pos->hists, fp); 1568 } 1569 1570 return ret; 1571 } 1572 1573 size_t perf_session__fprintf(struct perf_session *session, FILE *fp) 1574 { 1575 /* 1576 * FIXME: Here we have to actually print all the machines in this 1577 * session, not just the host... 1578 */ 1579 return machine__fprintf(&session->host_machine, fp); 1580 } 1581 1582 void perf_session__remove_thread(struct perf_session *session, 1583 struct thread *th) 1584 { 1585 /* 1586 * FIXME: This one makes no sense, we need to remove the thread from 1587 * the machine it belongs to, perf_session can have many machines, so 1588 * doing it always on ->host_machine is wrong. Fix when auditing all 1589 * the 'perf kvm' code. 1590 */ 1591 machine__remove_thread(&session->host_machine, th); 1592 } 1593 1594 struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, 1595 unsigned int type) 1596 { 1597 struct perf_evsel *pos; 1598 1599 list_for_each_entry(pos, &session->evlist->entries, node) { 1600 if (pos->attr.type == type) 1601 return pos; 1602 } 1603 return NULL; 1604 } 1605 1606 void perf_evsel__print_ip(struct perf_evsel *evsel, union perf_event *event, 1607 struct perf_sample *sample, struct machine *machine, 1608 int print_sym, int print_dso, int print_symoffset) 1609 { 1610 struct addr_location al; 1611 struct callchain_cursor_node *node; 1612 1613 if (perf_event__preprocess_sample(event, machine, &al, sample, 1614 NULL) < 0) { 1615 error("problem processing %d event, skipping it.\n", 1616 event->header.type); 1617 return; 1618 } 1619 1620 if (symbol_conf.use_callchain && sample->callchain) { 1621 1622 1623 if (machine__resolve_callchain(machine, evsel, al.thread, 1624 sample, NULL) != 0) { 1625 if (verbose) 1626 error("Failed to resolve callchain. Skipping\n"); 1627 return; 1628 } 1629 callchain_cursor_commit(&callchain_cursor); 1630 1631 while (1) { 1632 node = callchain_cursor_current(&callchain_cursor); 1633 if (!node) 1634 break; 1635 1636 printf("\t%16" PRIx64, node->ip); 1637 if (print_sym) { 1638 printf(" "); 1639 symbol__fprintf_symname(node->sym, stdout); 1640 } 1641 if (print_dso) { 1642 printf(" ("); 1643 map__fprintf_dsoname(node->map, stdout); 1644 printf(")"); 1645 } 1646 printf("\n"); 1647 1648 callchain_cursor_advance(&callchain_cursor); 1649 } 1650 1651 } else { 1652 printf("%16" PRIx64, sample->ip); 1653 if (print_sym) { 1654 printf(" "); 1655 if (print_symoffset) 1656 symbol__fprintf_symname_offs(al.sym, &al, 1657 stdout); 1658 else 1659 symbol__fprintf_symname(al.sym, stdout); 1660 } 1661 1662 if (print_dso) { 1663 printf(" ("); 1664 map__fprintf_dsoname(al.map, stdout); 1665 printf(")"); 1666 } 1667 } 1668 } 1669 1670 int perf_session__cpu_bitmap(struct perf_session *session, 1671 const char *cpu_list, unsigned long *cpu_bitmap) 1672 { 1673 int i; 1674 struct cpu_map *map; 1675 1676 for (i = 0; i < PERF_TYPE_MAX; ++i) { 1677 struct perf_evsel *evsel; 1678 1679 evsel = perf_session__find_first_evtype(session, i); 1680 if (!evsel) 1681 continue; 1682 1683 if (!(evsel->attr.sample_type & PERF_SAMPLE_CPU)) { 1684 pr_err("File does not contain CPU events. " 1685 "Remove -c option to proceed.\n"); 1686 return -1; 1687 } 1688 } 1689 1690 map = cpu_map__new(cpu_list); 1691 if (map == NULL) { 1692 pr_err("Invalid cpu_list\n"); 1693 return -1; 1694 } 1695 1696 for (i = 0; i < map->nr; i++) { 1697 int cpu = map->map[i]; 1698 1699 if (cpu >= MAX_NR_CPUS) { 1700 pr_err("Requested CPU %d too large. " 1701 "Consider raising MAX_NR_CPUS\n", cpu); 1702 return -1; 1703 } 1704 1705 set_bit(cpu, cpu_bitmap); 1706 } 1707 1708 return 0; 1709 } 1710 1711 void perf_session__fprintf_info(struct perf_session *session, FILE *fp, 1712 bool full) 1713 { 1714 struct stat st; 1715 int ret; 1716 1717 if (session == NULL || fp == NULL) 1718 return; 1719 1720 ret = fstat(session->fd, &st); 1721 if (ret == -1) 1722 return; 1723 1724 fprintf(fp, "# ========\n"); 1725 fprintf(fp, "# captured on: %s", ctime(&st.st_ctime)); 1726 perf_header__fprintf_info(session, fp, full); 1727 fprintf(fp, "# ========\n#\n"); 1728 } 1729 1730 1731 int __perf_session__set_tracepoints_handlers(struct perf_session *session, 1732 const struct perf_evsel_str_handler *assocs, 1733 size_t nr_assocs) 1734 { 1735 struct perf_evlist *evlist = session->evlist; 1736 struct event_format *format; 1737 struct perf_evsel *evsel; 1738 char *tracepoint, *name; 1739 size_t i; 1740 int err; 1741 1742 for (i = 0; i < nr_assocs; i++) { 1743 err = -ENOMEM; 1744 tracepoint = strdup(assocs[i].name); 1745 if (tracepoint == NULL) 1746 goto out; 1747 1748 err = -ENOENT; 1749 name = strchr(tracepoint, ':'); 1750 if (name == NULL) 1751 goto out_free; 1752 1753 *name++ = '\0'; 1754 format = pevent_find_event_by_name(session->pevent, 1755 tracepoint, name); 1756 if (format == NULL) { 1757 /* 1758 * Adding a handler for an event not in the session, 1759 * just ignore it. 1760 */ 1761 goto next; 1762 } 1763 1764 evsel = perf_evlist__find_tracepoint_by_id(evlist, format->id); 1765 if (evsel == NULL) 1766 goto next; 1767 1768 err = -EEXIST; 1769 if (evsel->handler.func != NULL) 1770 goto out_free; 1771 evsel->handler.func = assocs[i].handler; 1772 next: 1773 free(tracepoint); 1774 } 1775 1776 err = 0; 1777 out: 1778 return err; 1779 1780 out_free: 1781 free(tracepoint); 1782 goto out; 1783 } 1784