1 #include <dirent.h> 2 #include <errno.h> 3 #include <fcntl.h> 4 #include <inttypes.h> 5 #include <linux/kernel.h> 6 #include <linux/types.h> 7 #include <sys/types.h> 8 #include <sys/stat.h> 9 #include <unistd.h> 10 #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ 11 #include <api/fs/fs.h> 12 #include <linux/perf_event.h> 13 #include <linux/zalloc.h> 14 #include "event.h" 15 #include "debug.h" 16 #include "hist.h" 17 #include "machine.h" 18 #include "sort.h" 19 #include "string2.h" 20 #include "strlist.h" 21 #include "thread.h" 22 #include "thread_map.h" 23 #include "time-utils.h" 24 #include <linux/ctype.h> 25 #include "map.h" 26 #include "symbol.h" 27 #include "symbol/kallsyms.h" 28 #include "asm/bug.h" 29 #include "stat.h" 30 #include "session.h" 31 #include "bpf-event.h" 32 #include "../perf.h" 33 34 #define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500 35 36 static const char *perf_event__names[] = { 37 [0] = "TOTAL", 38 [PERF_RECORD_MMAP] = "MMAP", 39 [PERF_RECORD_MMAP2] = "MMAP2", 40 [PERF_RECORD_LOST] = "LOST", 41 [PERF_RECORD_COMM] = "COMM", 42 [PERF_RECORD_EXIT] = "EXIT", 43 [PERF_RECORD_THROTTLE] = "THROTTLE", 44 [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE", 45 [PERF_RECORD_FORK] = "FORK", 46 [PERF_RECORD_READ] = "READ", 47 [PERF_RECORD_SAMPLE] = "SAMPLE", 48 [PERF_RECORD_AUX] = "AUX", 49 [PERF_RECORD_ITRACE_START] = "ITRACE_START", 50 [PERF_RECORD_LOST_SAMPLES] = "LOST_SAMPLES", 51 [PERF_RECORD_SWITCH] = "SWITCH", 52 [PERF_RECORD_SWITCH_CPU_WIDE] = "SWITCH_CPU_WIDE", 53 [PERF_RECORD_NAMESPACES] = "NAMESPACES", 54 [PERF_RECORD_KSYMBOL] = "KSYMBOL", 55 [PERF_RECORD_BPF_EVENT] = "BPF_EVENT", 56 [PERF_RECORD_HEADER_ATTR] = "ATTR", 57 [PERF_RECORD_HEADER_EVENT_TYPE] = "EVENT_TYPE", 58 [PERF_RECORD_HEADER_TRACING_DATA] = "TRACING_DATA", 59 [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", 60 [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", 61 [PERF_RECORD_ID_INDEX] = "ID_INDEX", 62 [PERF_RECORD_AUXTRACE_INFO] = "AUXTRACE_INFO", 63 [PERF_RECORD_AUXTRACE] = "AUXTRACE", 64 [PERF_RECORD_AUXTRACE_ERROR] = "AUXTRACE_ERROR", 65 [PERF_RECORD_THREAD_MAP] = "THREAD_MAP", 66 [PERF_RECORD_CPU_MAP] = "CPU_MAP", 67 [PERF_RECORD_STAT_CONFIG] = "STAT_CONFIG", 68 [PERF_RECORD_STAT] = "STAT", 69 [PERF_RECORD_STAT_ROUND] = "STAT_ROUND", 70 [PERF_RECORD_EVENT_UPDATE] = "EVENT_UPDATE", 71 [PERF_RECORD_TIME_CONV] = "TIME_CONV", 72 [PERF_RECORD_HEADER_FEATURE] = "FEATURE", 73 [PERF_RECORD_COMPRESSED] = "COMPRESSED", 74 }; 75 76 static const char *perf_ns__names[] = { 77 [NET_NS_INDEX] = "net", 78 [UTS_NS_INDEX] = "uts", 79 [IPC_NS_INDEX] = "ipc", 80 [PID_NS_INDEX] = "pid", 81 [USER_NS_INDEX] = "user", 82 [MNT_NS_INDEX] = "mnt", 83 [CGROUP_NS_INDEX] = "cgroup", 84 }; 85 86 unsigned int proc_map_timeout = DEFAULT_PROC_MAP_PARSE_TIMEOUT; 87 88 const char *perf_event__name(unsigned int id) 89 { 90 if (id >= ARRAY_SIZE(perf_event__names)) 91 return "INVALID"; 92 if (!perf_event__names[id]) 93 return "UNKNOWN"; 94 return perf_event__names[id]; 95 } 96 97 static const char *perf_ns__name(unsigned int id) 98 { 99 if (id >= ARRAY_SIZE(perf_ns__names)) 100 return "UNKNOWN"; 101 return perf_ns__names[id]; 102 } 103 104 int perf_tool__process_synth_event(struct perf_tool *tool, 105 union perf_event *event, 106 struct machine *machine, 107 perf_event__handler_t process) 108 { 109 struct perf_sample synth_sample = { 110 .pid = -1, 111 .tid = -1, 112 .time = -1, 113 .stream_id = -1, 114 .cpu = -1, 115 .period = 1, 116 .cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK, 117 }; 118 119 return process(tool, event, &synth_sample, machine); 120 }; 121 122 /* 123 * Assumes that the first 4095 bytes of /proc/pid/stat contains 124 * the comm, tgid and ppid. 125 */ 126 static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, 127 pid_t *tgid, pid_t *ppid) 128 { 129 char filename[PATH_MAX]; 130 char bf[4096]; 131 int fd; 132 size_t size = 0; 133 ssize_t n; 134 char *name, *tgids, *ppids; 135 136 *tgid = -1; 137 *ppid = -1; 138 139 snprintf(filename, sizeof(filename), "/proc/%d/status", pid); 140 141 fd = open(filename, O_RDONLY); 142 if (fd < 0) { 143 pr_debug("couldn't open %s\n", filename); 144 return -1; 145 } 146 147 n = read(fd, bf, sizeof(bf) - 1); 148 close(fd); 149 if (n <= 0) { 150 pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", 151 pid); 152 return -1; 153 } 154 bf[n] = '\0'; 155 156 name = strstr(bf, "Name:"); 157 tgids = strstr(bf, "Tgid:"); 158 ppids = strstr(bf, "PPid:"); 159 160 if (name) { 161 char *nl; 162 163 name = skip_spaces(name + 5); /* strlen("Name:") */ 164 nl = strchr(name, '\n'); 165 if (nl) 166 *nl = '\0'; 167 168 size = strlen(name); 169 if (size >= len) 170 size = len - 1; 171 memcpy(comm, name, size); 172 comm[size] = '\0'; 173 } else { 174 pr_debug("Name: string not found for pid %d\n", pid); 175 } 176 177 if (tgids) { 178 tgids += 5; /* strlen("Tgid:") */ 179 *tgid = atoi(tgids); 180 } else { 181 pr_debug("Tgid: string not found for pid %d\n", pid); 182 } 183 184 if (ppids) { 185 ppids += 5; /* strlen("PPid:") */ 186 *ppid = atoi(ppids); 187 } else { 188 pr_debug("PPid: string not found for pid %d\n", pid); 189 } 190 191 return 0; 192 } 193 194 static int perf_event__prepare_comm(union perf_event *event, pid_t pid, 195 struct machine *machine, 196 pid_t *tgid, pid_t *ppid) 197 { 198 size_t size; 199 200 *ppid = -1; 201 202 memset(&event->comm, 0, sizeof(event->comm)); 203 204 if (machine__is_host(machine)) { 205 if (perf_event__get_comm_ids(pid, event->comm.comm, 206 sizeof(event->comm.comm), 207 tgid, ppid) != 0) { 208 return -1; 209 } 210 } else { 211 *tgid = machine->pid; 212 } 213 214 if (*tgid < 0) 215 return -1; 216 217 event->comm.pid = *tgid; 218 event->comm.header.type = PERF_RECORD_COMM; 219 220 size = strlen(event->comm.comm) + 1; 221 size = PERF_ALIGN(size, sizeof(u64)); 222 memset(event->comm.comm + size, 0, machine->id_hdr_size); 223 event->comm.header.size = (sizeof(event->comm) - 224 (sizeof(event->comm.comm) - size) + 225 machine->id_hdr_size); 226 event->comm.tid = pid; 227 228 return 0; 229 } 230 231 pid_t perf_event__synthesize_comm(struct perf_tool *tool, 232 union perf_event *event, pid_t pid, 233 perf_event__handler_t process, 234 struct machine *machine) 235 { 236 pid_t tgid, ppid; 237 238 if (perf_event__prepare_comm(event, pid, machine, &tgid, &ppid) != 0) 239 return -1; 240 241 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) 242 return -1; 243 244 return tgid; 245 } 246 247 static void perf_event__get_ns_link_info(pid_t pid, const char *ns, 248 struct perf_ns_link_info *ns_link_info) 249 { 250 struct stat64 st; 251 char proc_ns[128]; 252 253 sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns); 254 if (stat64(proc_ns, &st) == 0) { 255 ns_link_info->dev = st.st_dev; 256 ns_link_info->ino = st.st_ino; 257 } 258 } 259 260 int perf_event__synthesize_namespaces(struct perf_tool *tool, 261 union perf_event *event, 262 pid_t pid, pid_t tgid, 263 perf_event__handler_t process, 264 struct machine *machine) 265 { 266 u32 idx; 267 struct perf_ns_link_info *ns_link_info; 268 269 if (!tool || !tool->namespace_events) 270 return 0; 271 272 memset(&event->namespaces, 0, (sizeof(event->namespaces) + 273 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 274 machine->id_hdr_size)); 275 276 event->namespaces.pid = tgid; 277 event->namespaces.tid = pid; 278 279 event->namespaces.nr_namespaces = NR_NAMESPACES; 280 281 ns_link_info = event->namespaces.link_info; 282 283 for (idx = 0; idx < event->namespaces.nr_namespaces; idx++) 284 perf_event__get_ns_link_info(pid, perf_ns__name(idx), 285 &ns_link_info[idx]); 286 287 event->namespaces.header.type = PERF_RECORD_NAMESPACES; 288 289 event->namespaces.header.size = (sizeof(event->namespaces) + 290 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 291 machine->id_hdr_size); 292 293 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) 294 return -1; 295 296 return 0; 297 } 298 299 static int perf_event__synthesize_fork(struct perf_tool *tool, 300 union perf_event *event, 301 pid_t pid, pid_t tgid, pid_t ppid, 302 perf_event__handler_t process, 303 struct machine *machine) 304 { 305 memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); 306 307 /* 308 * for main thread set parent to ppid from status file. For other 309 * threads set parent pid to main thread. ie., assume main thread 310 * spawns all threads in a process 311 */ 312 if (tgid == pid) { 313 event->fork.ppid = ppid; 314 event->fork.ptid = ppid; 315 } else { 316 event->fork.ppid = tgid; 317 event->fork.ptid = tgid; 318 } 319 event->fork.pid = tgid; 320 event->fork.tid = pid; 321 event->fork.header.type = PERF_RECORD_FORK; 322 event->fork.header.misc = PERF_RECORD_MISC_FORK_EXEC; 323 324 event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size); 325 326 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) 327 return -1; 328 329 return 0; 330 } 331 332 int perf_event__synthesize_mmap_events(struct perf_tool *tool, 333 union perf_event *event, 334 pid_t pid, pid_t tgid, 335 perf_event__handler_t process, 336 struct machine *machine, 337 bool mmap_data) 338 { 339 char filename[PATH_MAX]; 340 FILE *fp; 341 unsigned long long t; 342 bool truncation = false; 343 unsigned long long timeout = proc_map_timeout * 1000000ULL; 344 int rc = 0; 345 const char *hugetlbfs_mnt = hugetlbfs__mountpoint(); 346 int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0; 347 348 if (machine__is_default_guest(machine)) 349 return 0; 350 351 snprintf(filename, sizeof(filename), "%s/proc/%d/task/%d/maps", 352 machine->root_dir, pid, pid); 353 354 fp = fopen(filename, "r"); 355 if (fp == NULL) { 356 /* 357 * We raced with a task exiting - just return: 358 */ 359 pr_debug("couldn't open %s\n", filename); 360 return -1; 361 } 362 363 event->header.type = PERF_RECORD_MMAP2; 364 t = rdclock(); 365 366 while (1) { 367 char bf[BUFSIZ]; 368 char prot[5]; 369 char execname[PATH_MAX]; 370 char anonstr[] = "//anon"; 371 unsigned int ino; 372 size_t size; 373 ssize_t n; 374 375 if (fgets(bf, sizeof(bf), fp) == NULL) 376 break; 377 378 if ((rdclock() - t) > timeout) { 379 pr_warning("Reading %s time out. " 380 "You may want to increase " 381 "the time limit by --proc-map-timeout\n", 382 filename); 383 truncation = true; 384 goto out; 385 } 386 387 /* ensure null termination since stack will be reused. */ 388 strcpy(execname, ""); 389 390 /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ 391 n = sscanf(bf, "%"PRI_lx64"-%"PRI_lx64" %s %"PRI_lx64" %x:%x %u %[^\n]\n", 392 &event->mmap2.start, &event->mmap2.len, prot, 393 &event->mmap2.pgoff, &event->mmap2.maj, 394 &event->mmap2.min, 395 &ino, execname); 396 397 /* 398 * Anon maps don't have the execname. 399 */ 400 if (n < 7) 401 continue; 402 403 event->mmap2.ino = (u64)ino; 404 405 /* 406 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c 407 */ 408 if (machine__is_host(machine)) 409 event->header.misc = PERF_RECORD_MISC_USER; 410 else 411 event->header.misc = PERF_RECORD_MISC_GUEST_USER; 412 413 /* map protection and flags bits */ 414 event->mmap2.prot = 0; 415 event->mmap2.flags = 0; 416 if (prot[0] == 'r') 417 event->mmap2.prot |= PROT_READ; 418 if (prot[1] == 'w') 419 event->mmap2.prot |= PROT_WRITE; 420 if (prot[2] == 'x') 421 event->mmap2.prot |= PROT_EXEC; 422 423 if (prot[3] == 's') 424 event->mmap2.flags |= MAP_SHARED; 425 else 426 event->mmap2.flags |= MAP_PRIVATE; 427 428 if (prot[2] != 'x') { 429 if (!mmap_data || prot[0] != 'r') 430 continue; 431 432 event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; 433 } 434 435 out: 436 if (truncation) 437 event->header.misc |= PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT; 438 439 if (!strcmp(execname, "")) 440 strcpy(execname, anonstr); 441 442 if (hugetlbfs_mnt_len && 443 !strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) { 444 strcpy(execname, anonstr); 445 event->mmap2.flags |= MAP_HUGETLB; 446 } 447 448 size = strlen(execname) + 1; 449 memcpy(event->mmap2.filename, execname, size); 450 size = PERF_ALIGN(size, sizeof(u64)); 451 event->mmap2.len -= event->mmap.start; 452 event->mmap2.header.size = (sizeof(event->mmap2) - 453 (sizeof(event->mmap2.filename) - size)); 454 memset(event->mmap2.filename + size, 0, machine->id_hdr_size); 455 event->mmap2.header.size += machine->id_hdr_size; 456 event->mmap2.pid = tgid; 457 event->mmap2.tid = pid; 458 459 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { 460 rc = -1; 461 break; 462 } 463 464 if (truncation) 465 break; 466 } 467 468 fclose(fp); 469 return rc; 470 } 471 472 int perf_event__synthesize_modules(struct perf_tool *tool, 473 perf_event__handler_t process, 474 struct machine *machine) 475 { 476 int rc = 0; 477 struct map *pos; 478 struct maps *maps = machine__kernel_maps(machine); 479 union perf_event *event = zalloc((sizeof(event->mmap) + 480 machine->id_hdr_size)); 481 if (event == NULL) { 482 pr_debug("Not enough memory synthesizing mmap event " 483 "for kernel modules\n"); 484 return -1; 485 } 486 487 event->header.type = PERF_RECORD_MMAP; 488 489 /* 490 * kernel uses 0 for user space maps, see kernel/perf_event.c 491 * __perf_event_mmap 492 */ 493 if (machine__is_host(machine)) 494 event->header.misc = PERF_RECORD_MISC_KERNEL; 495 else 496 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 497 498 for (pos = maps__first(maps); pos; pos = map__next(pos)) { 499 size_t size; 500 501 if (!__map__is_kmodule(pos)) 502 continue; 503 504 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); 505 event->mmap.header.type = PERF_RECORD_MMAP; 506 event->mmap.header.size = (sizeof(event->mmap) - 507 (sizeof(event->mmap.filename) - size)); 508 memset(event->mmap.filename + size, 0, machine->id_hdr_size); 509 event->mmap.header.size += machine->id_hdr_size; 510 event->mmap.start = pos->start; 511 event->mmap.len = pos->end - pos->start; 512 event->mmap.pid = machine->pid; 513 514 memcpy(event->mmap.filename, pos->dso->long_name, 515 pos->dso->long_name_len + 1); 516 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { 517 rc = -1; 518 break; 519 } 520 } 521 522 free(event); 523 return rc; 524 } 525 526 static int __event__synthesize_thread(union perf_event *comm_event, 527 union perf_event *mmap_event, 528 union perf_event *fork_event, 529 union perf_event *namespaces_event, 530 pid_t pid, int full, 531 perf_event__handler_t process, 532 struct perf_tool *tool, 533 struct machine *machine, 534 bool mmap_data) 535 { 536 char filename[PATH_MAX]; 537 DIR *tasks; 538 struct dirent *dirent; 539 pid_t tgid, ppid; 540 int rc = 0; 541 542 /* special case: only send one comm event using passed in pid */ 543 if (!full) { 544 tgid = perf_event__synthesize_comm(tool, comm_event, pid, 545 process, machine); 546 547 if (tgid == -1) 548 return -1; 549 550 if (perf_event__synthesize_namespaces(tool, namespaces_event, pid, 551 tgid, process, machine) < 0) 552 return -1; 553 554 /* 555 * send mmap only for thread group leader 556 * see thread__init_map_groups 557 */ 558 if (pid == tgid && 559 perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 560 process, machine, mmap_data)) 561 return -1; 562 563 return 0; 564 } 565 566 if (machine__is_default_guest(machine)) 567 return 0; 568 569 snprintf(filename, sizeof(filename), "%s/proc/%d/task", 570 machine->root_dir, pid); 571 572 tasks = opendir(filename); 573 if (tasks == NULL) { 574 pr_debug("couldn't open %s\n", filename); 575 return 0; 576 } 577 578 while ((dirent = readdir(tasks)) != NULL) { 579 char *end; 580 pid_t _pid; 581 582 _pid = strtol(dirent->d_name, &end, 10); 583 if (*end) 584 continue; 585 586 rc = -1; 587 if (perf_event__prepare_comm(comm_event, _pid, machine, 588 &tgid, &ppid) != 0) 589 break; 590 591 if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, 592 ppid, process, machine) < 0) 593 break; 594 595 if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid, 596 tgid, process, machine) < 0) 597 break; 598 599 /* 600 * Send the prepared comm event 601 */ 602 if (perf_tool__process_synth_event(tool, comm_event, machine, process) != 0) 603 break; 604 605 rc = 0; 606 if (_pid == pid) { 607 /* process the parent's maps too */ 608 rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 609 process, machine, mmap_data); 610 if (rc) 611 break; 612 } 613 } 614 615 closedir(tasks); 616 return rc; 617 } 618 619 int perf_event__synthesize_thread_map(struct perf_tool *tool, 620 struct perf_thread_map *threads, 621 perf_event__handler_t process, 622 struct machine *machine, 623 bool mmap_data) 624 { 625 union perf_event *comm_event, *mmap_event, *fork_event; 626 union perf_event *namespaces_event; 627 int err = -1, thread, j; 628 629 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 630 if (comm_event == NULL) 631 goto out; 632 633 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); 634 if (mmap_event == NULL) 635 goto out_free_comm; 636 637 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); 638 if (fork_event == NULL) 639 goto out_free_mmap; 640 641 namespaces_event = malloc(sizeof(namespaces_event->namespaces) + 642 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 643 machine->id_hdr_size); 644 if (namespaces_event == NULL) 645 goto out_free_fork; 646 647 err = 0; 648 for (thread = 0; thread < threads->nr; ++thread) { 649 if (__event__synthesize_thread(comm_event, mmap_event, 650 fork_event, namespaces_event, 651 perf_thread_map__pid(threads, thread), 0, 652 process, tool, machine, 653 mmap_data)) { 654 err = -1; 655 break; 656 } 657 658 /* 659 * comm.pid is set to thread group id by 660 * perf_event__synthesize_comm 661 */ 662 if ((int) comm_event->comm.pid != perf_thread_map__pid(threads, thread)) { 663 bool need_leader = true; 664 665 /* is thread group leader in thread_map? */ 666 for (j = 0; j < threads->nr; ++j) { 667 if ((int) comm_event->comm.pid == perf_thread_map__pid(threads, j)) { 668 need_leader = false; 669 break; 670 } 671 } 672 673 /* if not, generate events for it */ 674 if (need_leader && 675 __event__synthesize_thread(comm_event, mmap_event, 676 fork_event, namespaces_event, 677 comm_event->comm.pid, 0, 678 process, tool, machine, 679 mmap_data)) { 680 err = -1; 681 break; 682 } 683 } 684 } 685 free(namespaces_event); 686 out_free_fork: 687 free(fork_event); 688 out_free_mmap: 689 free(mmap_event); 690 out_free_comm: 691 free(comm_event); 692 out: 693 return err; 694 } 695 696 static int __perf_event__synthesize_threads(struct perf_tool *tool, 697 perf_event__handler_t process, 698 struct machine *machine, 699 bool mmap_data, 700 struct dirent **dirent, 701 int start, 702 int num) 703 { 704 union perf_event *comm_event, *mmap_event, *fork_event; 705 union perf_event *namespaces_event; 706 int err = -1; 707 char *end; 708 pid_t pid; 709 int i; 710 711 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 712 if (comm_event == NULL) 713 goto out; 714 715 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); 716 if (mmap_event == NULL) 717 goto out_free_comm; 718 719 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); 720 if (fork_event == NULL) 721 goto out_free_mmap; 722 723 namespaces_event = malloc(sizeof(namespaces_event->namespaces) + 724 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 725 machine->id_hdr_size); 726 if (namespaces_event == NULL) 727 goto out_free_fork; 728 729 for (i = start; i < start + num; i++) { 730 if (!isdigit(dirent[i]->d_name[0])) 731 continue; 732 733 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10); 734 /* only interested in proper numerical dirents */ 735 if (*end) 736 continue; 737 /* 738 * We may race with exiting thread, so don't stop just because 739 * one thread couldn't be synthesized. 740 */ 741 __event__synthesize_thread(comm_event, mmap_event, fork_event, 742 namespaces_event, pid, 1, process, 743 tool, machine, mmap_data); 744 } 745 err = 0; 746 747 free(namespaces_event); 748 out_free_fork: 749 free(fork_event); 750 out_free_mmap: 751 free(mmap_event); 752 out_free_comm: 753 free(comm_event); 754 out: 755 return err; 756 } 757 758 struct synthesize_threads_arg { 759 struct perf_tool *tool; 760 perf_event__handler_t process; 761 struct machine *machine; 762 bool mmap_data; 763 struct dirent **dirent; 764 int num; 765 int start; 766 }; 767 768 static void *synthesize_threads_worker(void *arg) 769 { 770 struct synthesize_threads_arg *args = arg; 771 772 __perf_event__synthesize_threads(args->tool, args->process, 773 args->machine, args->mmap_data, 774 args->dirent, 775 args->start, args->num); 776 return NULL; 777 } 778 779 int perf_event__synthesize_threads(struct perf_tool *tool, 780 perf_event__handler_t process, 781 struct machine *machine, 782 bool mmap_data, 783 unsigned int nr_threads_synthesize) 784 { 785 struct synthesize_threads_arg *args = NULL; 786 pthread_t *synthesize_threads = NULL; 787 char proc_path[PATH_MAX]; 788 struct dirent **dirent; 789 int num_per_thread; 790 int m, n, i, j; 791 int thread_nr; 792 int base = 0; 793 int err = -1; 794 795 796 if (machine__is_default_guest(machine)) 797 return 0; 798 799 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); 800 n = scandir(proc_path, &dirent, 0, alphasort); 801 if (n < 0) 802 return err; 803 804 if (nr_threads_synthesize == UINT_MAX) 805 thread_nr = sysconf(_SC_NPROCESSORS_ONLN); 806 else 807 thread_nr = nr_threads_synthesize; 808 809 if (thread_nr <= 1) { 810 err = __perf_event__synthesize_threads(tool, process, 811 machine, mmap_data, 812 dirent, base, n); 813 goto free_dirent; 814 } 815 if (thread_nr > n) 816 thread_nr = n; 817 818 synthesize_threads = calloc(sizeof(pthread_t), thread_nr); 819 if (synthesize_threads == NULL) 820 goto free_dirent; 821 822 args = calloc(sizeof(*args), thread_nr); 823 if (args == NULL) 824 goto free_threads; 825 826 num_per_thread = n / thread_nr; 827 m = n % thread_nr; 828 for (i = 0; i < thread_nr; i++) { 829 args[i].tool = tool; 830 args[i].process = process; 831 args[i].machine = machine; 832 args[i].mmap_data = mmap_data; 833 args[i].dirent = dirent; 834 } 835 for (i = 0; i < m; i++) { 836 args[i].num = num_per_thread + 1; 837 args[i].start = i * args[i].num; 838 } 839 if (i != 0) 840 base = args[i-1].start + args[i-1].num; 841 for (j = i; j < thread_nr; j++) { 842 args[j].num = num_per_thread; 843 args[j].start = base + (j - i) * args[i].num; 844 } 845 846 for (i = 0; i < thread_nr; i++) { 847 if (pthread_create(&synthesize_threads[i], NULL, 848 synthesize_threads_worker, &args[i])) 849 goto out_join; 850 } 851 err = 0; 852 out_join: 853 for (i = 0; i < thread_nr; i++) 854 pthread_join(synthesize_threads[i], NULL); 855 free(args); 856 free_threads: 857 free(synthesize_threads); 858 free_dirent: 859 for (i = 0; i < n; i++) 860 zfree(&dirent[i]); 861 free(dirent); 862 863 return err; 864 } 865 866 struct process_symbol_args { 867 const char *name; 868 u64 start; 869 }; 870 871 static int find_symbol_cb(void *arg, const char *name, char type, 872 u64 start) 873 { 874 struct process_symbol_args *args = arg; 875 876 /* 877 * Must be a function or at least an alias, as in PARISC64, where "_text" is 878 * an 'A' to the same address as "_stext". 879 */ 880 if (!(kallsyms__is_function(type) || 881 type == 'A') || strcmp(name, args->name)) 882 return 0; 883 884 args->start = start; 885 return 1; 886 } 887 888 int kallsyms__get_function_start(const char *kallsyms_filename, 889 const char *symbol_name, u64 *addr) 890 { 891 struct process_symbol_args args = { .name = symbol_name, }; 892 893 if (kallsyms__parse(kallsyms_filename, &args, find_symbol_cb) <= 0) 894 return -1; 895 896 *addr = args.start; 897 return 0; 898 } 899 900 int __weak perf_event__synthesize_extra_kmaps(struct perf_tool *tool __maybe_unused, 901 perf_event__handler_t process __maybe_unused, 902 struct machine *machine __maybe_unused) 903 { 904 return 0; 905 } 906 907 static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, 908 perf_event__handler_t process, 909 struct machine *machine) 910 { 911 size_t size; 912 struct map *map = machine__kernel_map(machine); 913 struct kmap *kmap; 914 int err; 915 union perf_event *event; 916 917 if (map == NULL) 918 return -1; 919 920 kmap = map__kmap(map); 921 if (!kmap->ref_reloc_sym) 922 return -1; 923 924 /* 925 * We should get this from /sys/kernel/sections/.text, but till that is 926 * available use this, and after it is use this as a fallback for older 927 * kernels. 928 */ 929 event = zalloc((sizeof(event->mmap) + machine->id_hdr_size)); 930 if (event == NULL) { 931 pr_debug("Not enough memory synthesizing mmap event " 932 "for kernel modules\n"); 933 return -1; 934 } 935 936 if (machine__is_host(machine)) { 937 /* 938 * kernel uses PERF_RECORD_MISC_USER for user space maps, 939 * see kernel/perf_event.c __perf_event_mmap 940 */ 941 event->header.misc = PERF_RECORD_MISC_KERNEL; 942 } else { 943 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 944 } 945 946 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), 947 "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1; 948 size = PERF_ALIGN(size, sizeof(u64)); 949 event->mmap.header.type = PERF_RECORD_MMAP; 950 event->mmap.header.size = (sizeof(event->mmap) - 951 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); 952 event->mmap.pgoff = kmap->ref_reloc_sym->addr; 953 event->mmap.start = map->start; 954 event->mmap.len = map->end - event->mmap.start; 955 event->mmap.pid = machine->pid; 956 957 err = perf_tool__process_synth_event(tool, event, machine, process); 958 free(event); 959 960 return err; 961 } 962 963 int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, 964 perf_event__handler_t process, 965 struct machine *machine) 966 { 967 int err; 968 969 err = __perf_event__synthesize_kernel_mmap(tool, process, machine); 970 if (err < 0) 971 return err; 972 973 return perf_event__synthesize_extra_kmaps(tool, process, machine); 974 } 975 976 int perf_event__synthesize_thread_map2(struct perf_tool *tool, 977 struct perf_thread_map *threads, 978 perf_event__handler_t process, 979 struct machine *machine) 980 { 981 union perf_event *event; 982 int i, err, size; 983 984 size = sizeof(event->thread_map); 985 size += threads->nr * sizeof(event->thread_map.entries[0]); 986 987 event = zalloc(size); 988 if (!event) 989 return -ENOMEM; 990 991 event->header.type = PERF_RECORD_THREAD_MAP; 992 event->header.size = size; 993 event->thread_map.nr = threads->nr; 994 995 for (i = 0; i < threads->nr; i++) { 996 struct perf_record_thread_map_entry *entry = &event->thread_map.entries[i]; 997 char *comm = perf_thread_map__comm(threads, i); 998 999 if (!comm) 1000 comm = (char *) ""; 1001 1002 entry->pid = perf_thread_map__pid(threads, i); 1003 strncpy((char *) &entry->comm, comm, sizeof(entry->comm)); 1004 } 1005 1006 err = process(tool, event, NULL, machine); 1007 1008 free(event); 1009 return err; 1010 } 1011 1012 static void synthesize_cpus(struct cpu_map_entries *cpus, 1013 struct perf_cpu_map *map) 1014 { 1015 int i; 1016 1017 cpus->nr = map->nr; 1018 1019 for (i = 0; i < map->nr; i++) 1020 cpus->cpu[i] = map->map[i]; 1021 } 1022 1023 static void synthesize_mask(struct perf_record_record_cpu_map *mask, 1024 struct perf_cpu_map *map, int max) 1025 { 1026 int i; 1027 1028 mask->nr = BITS_TO_LONGS(max); 1029 mask->long_size = sizeof(long); 1030 1031 for (i = 0; i < map->nr; i++) 1032 set_bit(map->map[i], mask->mask); 1033 } 1034 1035 static size_t cpus_size(struct perf_cpu_map *map) 1036 { 1037 return sizeof(struct cpu_map_entries) + map->nr * sizeof(u16); 1038 } 1039 1040 static size_t mask_size(struct perf_cpu_map *map, int *max) 1041 { 1042 int i; 1043 1044 *max = 0; 1045 1046 for (i = 0; i < map->nr; i++) { 1047 /* bit possition of the cpu is + 1 */ 1048 int bit = map->map[i] + 1; 1049 1050 if (bit > *max) 1051 *max = bit; 1052 } 1053 1054 return sizeof(struct perf_record_record_cpu_map) + BITS_TO_LONGS(*max) * sizeof(long); 1055 } 1056 1057 void *cpu_map_data__alloc(struct perf_cpu_map *map, size_t *size, u16 *type, int *max) 1058 { 1059 size_t size_cpus, size_mask; 1060 bool is_dummy = perf_cpu_map__empty(map); 1061 1062 /* 1063 * Both array and mask data have variable size based 1064 * on the number of cpus and their actual values. 1065 * The size of the 'struct perf_record_cpu_map_data' is: 1066 * 1067 * array = size of 'struct cpu_map_entries' + 1068 * number of cpus * sizeof(u64) 1069 * 1070 * mask = size of 'struct perf_record_record_cpu_map' + 1071 * maximum cpu bit converted to size of longs 1072 * 1073 * and finaly + the size of 'struct perf_record_cpu_map_data'. 1074 */ 1075 size_cpus = cpus_size(map); 1076 size_mask = mask_size(map, max); 1077 1078 if (is_dummy || (size_cpus < size_mask)) { 1079 *size += size_cpus; 1080 *type = PERF_CPU_MAP__CPUS; 1081 } else { 1082 *size += size_mask; 1083 *type = PERF_CPU_MAP__MASK; 1084 } 1085 1086 *size += sizeof(struct perf_record_cpu_map_data); 1087 *size = PERF_ALIGN(*size, sizeof(u64)); 1088 return zalloc(*size); 1089 } 1090 1091 void cpu_map_data__synthesize(struct perf_record_cpu_map_data *data, struct perf_cpu_map *map, 1092 u16 type, int max) 1093 { 1094 data->type = type; 1095 1096 switch (type) { 1097 case PERF_CPU_MAP__CPUS: 1098 synthesize_cpus((struct cpu_map_entries *) data->data, map); 1099 break; 1100 case PERF_CPU_MAP__MASK: 1101 synthesize_mask((struct perf_record_record_cpu_map *)data->data, map, max); 1102 default: 1103 break; 1104 }; 1105 } 1106 1107 static struct perf_record_cpu_map *cpu_map_event__new(struct perf_cpu_map *map) 1108 { 1109 size_t size = sizeof(struct perf_record_cpu_map); 1110 struct perf_record_cpu_map *event; 1111 int max; 1112 u16 type; 1113 1114 event = cpu_map_data__alloc(map, &size, &type, &max); 1115 if (!event) 1116 return NULL; 1117 1118 event->header.type = PERF_RECORD_CPU_MAP; 1119 event->header.size = size; 1120 event->data.type = type; 1121 1122 cpu_map_data__synthesize(&event->data, map, type, max); 1123 return event; 1124 } 1125 1126 int perf_event__synthesize_cpu_map(struct perf_tool *tool, 1127 struct perf_cpu_map *map, 1128 perf_event__handler_t process, 1129 struct machine *machine) 1130 { 1131 struct perf_record_cpu_map *event; 1132 int err; 1133 1134 event = cpu_map_event__new(map); 1135 if (!event) 1136 return -ENOMEM; 1137 1138 err = process(tool, (union perf_event *) event, NULL, machine); 1139 1140 free(event); 1141 return err; 1142 } 1143 1144 int perf_event__synthesize_stat_config(struct perf_tool *tool, 1145 struct perf_stat_config *config, 1146 perf_event__handler_t process, 1147 struct machine *machine) 1148 { 1149 struct perf_record_stat_config *event; 1150 int size, i = 0, err; 1151 1152 size = sizeof(*event); 1153 size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0])); 1154 1155 event = zalloc(size); 1156 if (!event) 1157 return -ENOMEM; 1158 1159 event->header.type = PERF_RECORD_STAT_CONFIG; 1160 event->header.size = size; 1161 event->nr = PERF_STAT_CONFIG_TERM__MAX; 1162 1163 #define ADD(__term, __val) \ 1164 event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \ 1165 event->data[i].val = __val; \ 1166 i++; 1167 1168 ADD(AGGR_MODE, config->aggr_mode) 1169 ADD(INTERVAL, config->interval) 1170 ADD(SCALE, config->scale) 1171 1172 WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX, 1173 "stat config terms unbalanced\n"); 1174 #undef ADD 1175 1176 err = process(tool, (union perf_event *) event, NULL, machine); 1177 1178 free(event); 1179 return err; 1180 } 1181 1182 int perf_event__synthesize_stat(struct perf_tool *tool, 1183 u32 cpu, u32 thread, u64 id, 1184 struct perf_counts_values *count, 1185 perf_event__handler_t process, 1186 struct machine *machine) 1187 { 1188 struct perf_record_stat event; 1189 1190 event.header.type = PERF_RECORD_STAT; 1191 event.header.size = sizeof(event); 1192 event.header.misc = 0; 1193 1194 event.id = id; 1195 event.cpu = cpu; 1196 event.thread = thread; 1197 event.val = count->val; 1198 event.ena = count->ena; 1199 event.run = count->run; 1200 1201 return process(tool, (union perf_event *) &event, NULL, machine); 1202 } 1203 1204 int perf_event__synthesize_stat_round(struct perf_tool *tool, 1205 u64 evtime, u64 type, 1206 perf_event__handler_t process, 1207 struct machine *machine) 1208 { 1209 struct perf_record_stat_round event; 1210 1211 event.header.type = PERF_RECORD_STAT_ROUND; 1212 event.header.size = sizeof(event); 1213 event.header.misc = 0; 1214 1215 event.time = evtime; 1216 event.type = type; 1217 1218 return process(tool, (union perf_event *) &event, NULL, machine); 1219 } 1220 1221 void perf_event__read_stat_config(struct perf_stat_config *config, 1222 struct perf_record_stat_config *event) 1223 { 1224 unsigned i; 1225 1226 for (i = 0; i < event->nr; i++) { 1227 1228 switch (event->data[i].tag) { 1229 #define CASE(__term, __val) \ 1230 case PERF_STAT_CONFIG_TERM__##__term: \ 1231 config->__val = event->data[i].val; \ 1232 break; 1233 1234 CASE(AGGR_MODE, aggr_mode) 1235 CASE(SCALE, scale) 1236 CASE(INTERVAL, interval) 1237 #undef CASE 1238 default: 1239 pr_warning("unknown stat config term %" PRI_lu64 "\n", 1240 event->data[i].tag); 1241 } 1242 } 1243 } 1244 1245 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp) 1246 { 1247 const char *s; 1248 1249 if (event->header.misc & PERF_RECORD_MISC_COMM_EXEC) 1250 s = " exec"; 1251 else 1252 s = ""; 1253 1254 return fprintf(fp, "%s: %s:%d/%d\n", s, event->comm.comm, event->comm.pid, event->comm.tid); 1255 } 1256 1257 size_t perf_event__fprintf_namespaces(union perf_event *event, FILE *fp) 1258 { 1259 size_t ret = 0; 1260 struct perf_ns_link_info *ns_link_info; 1261 u32 nr_namespaces, idx; 1262 1263 ns_link_info = event->namespaces.link_info; 1264 nr_namespaces = event->namespaces.nr_namespaces; 1265 1266 ret += fprintf(fp, " %d/%d - nr_namespaces: %u\n\t\t[", 1267 event->namespaces.pid, 1268 event->namespaces.tid, 1269 nr_namespaces); 1270 1271 for (idx = 0; idx < nr_namespaces; idx++) { 1272 if (idx && (idx % 4 == 0)) 1273 ret += fprintf(fp, "\n\t\t "); 1274 1275 ret += fprintf(fp, "%u/%s: %" PRIu64 "/%#" PRIx64 "%s", idx, 1276 perf_ns__name(idx), (u64)ns_link_info[idx].dev, 1277 (u64)ns_link_info[idx].ino, 1278 ((idx + 1) != nr_namespaces) ? ", " : "]\n"); 1279 } 1280 1281 return ret; 1282 } 1283 1284 int perf_event__process_comm(struct perf_tool *tool __maybe_unused, 1285 union perf_event *event, 1286 struct perf_sample *sample, 1287 struct machine *machine) 1288 { 1289 return machine__process_comm_event(machine, event, sample); 1290 } 1291 1292 int perf_event__process_namespaces(struct perf_tool *tool __maybe_unused, 1293 union perf_event *event, 1294 struct perf_sample *sample, 1295 struct machine *machine) 1296 { 1297 return machine__process_namespaces_event(machine, event, sample); 1298 } 1299 1300 int perf_event__process_lost(struct perf_tool *tool __maybe_unused, 1301 union perf_event *event, 1302 struct perf_sample *sample, 1303 struct machine *machine) 1304 { 1305 return machine__process_lost_event(machine, event, sample); 1306 } 1307 1308 int perf_event__process_aux(struct perf_tool *tool __maybe_unused, 1309 union perf_event *event, 1310 struct perf_sample *sample __maybe_unused, 1311 struct machine *machine) 1312 { 1313 return machine__process_aux_event(machine, event); 1314 } 1315 1316 int perf_event__process_itrace_start(struct perf_tool *tool __maybe_unused, 1317 union perf_event *event, 1318 struct perf_sample *sample __maybe_unused, 1319 struct machine *machine) 1320 { 1321 return machine__process_itrace_start_event(machine, event); 1322 } 1323 1324 int perf_event__process_lost_samples(struct perf_tool *tool __maybe_unused, 1325 union perf_event *event, 1326 struct perf_sample *sample, 1327 struct machine *machine) 1328 { 1329 return machine__process_lost_samples_event(machine, event, sample); 1330 } 1331 1332 int perf_event__process_switch(struct perf_tool *tool __maybe_unused, 1333 union perf_event *event, 1334 struct perf_sample *sample __maybe_unused, 1335 struct machine *machine) 1336 { 1337 return machine__process_switch_event(machine, event); 1338 } 1339 1340 int perf_event__process_ksymbol(struct perf_tool *tool __maybe_unused, 1341 union perf_event *event, 1342 struct perf_sample *sample __maybe_unused, 1343 struct machine *machine) 1344 { 1345 return machine__process_ksymbol(machine, event, sample); 1346 } 1347 1348 int perf_event__process_bpf(struct perf_tool *tool __maybe_unused, 1349 union perf_event *event, 1350 struct perf_sample *sample, 1351 struct machine *machine) 1352 { 1353 return machine__process_bpf(machine, event, sample); 1354 } 1355 1356 size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) 1357 { 1358 return fprintf(fp, " %d/%d: [%#" PRI_lx64 "(%#" PRI_lx64 ") @ %#" PRI_lx64 "]: %c %s\n", 1359 event->mmap.pid, event->mmap.tid, event->mmap.start, 1360 event->mmap.len, event->mmap.pgoff, 1361 (event->header.misc & PERF_RECORD_MISC_MMAP_DATA) ? 'r' : 'x', 1362 event->mmap.filename); 1363 } 1364 1365 size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) 1366 { 1367 return fprintf(fp, " %d/%d: [%#" PRI_lx64 "(%#" PRI_lx64 ") @ %#" PRI_lx64 1368 " %02x:%02x %"PRI_lu64" %"PRI_lu64"]: %c%c%c%c %s\n", 1369 event->mmap2.pid, event->mmap2.tid, event->mmap2.start, 1370 event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, 1371 event->mmap2.min, event->mmap2.ino, 1372 event->mmap2.ino_generation, 1373 (event->mmap2.prot & PROT_READ) ? 'r' : '-', 1374 (event->mmap2.prot & PROT_WRITE) ? 'w' : '-', 1375 (event->mmap2.prot & PROT_EXEC) ? 'x' : '-', 1376 (event->mmap2.flags & MAP_SHARED) ? 's' : 'p', 1377 event->mmap2.filename); 1378 } 1379 1380 size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp) 1381 { 1382 struct perf_thread_map *threads = thread_map__new_event(&event->thread_map); 1383 size_t ret; 1384 1385 ret = fprintf(fp, " nr: "); 1386 1387 if (threads) 1388 ret += thread_map__fprintf(threads, fp); 1389 else 1390 ret += fprintf(fp, "failed to get threads from event\n"); 1391 1392 perf_thread_map__put(threads); 1393 return ret; 1394 } 1395 1396 size_t perf_event__fprintf_cpu_map(union perf_event *event, FILE *fp) 1397 { 1398 struct perf_cpu_map *cpus = cpu_map__new_data(&event->cpu_map.data); 1399 size_t ret; 1400 1401 ret = fprintf(fp, ": "); 1402 1403 if (cpus) 1404 ret += cpu_map__fprintf(cpus, fp); 1405 else 1406 ret += fprintf(fp, "failed to get cpumap from event\n"); 1407 1408 perf_cpu_map__put(cpus); 1409 return ret; 1410 } 1411 1412 int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, 1413 union perf_event *event, 1414 struct perf_sample *sample, 1415 struct machine *machine) 1416 { 1417 return machine__process_mmap_event(machine, event, sample); 1418 } 1419 1420 int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, 1421 union perf_event *event, 1422 struct perf_sample *sample, 1423 struct machine *machine) 1424 { 1425 return machine__process_mmap2_event(machine, event, sample); 1426 } 1427 1428 size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) 1429 { 1430 return fprintf(fp, "(%d:%d):(%d:%d)\n", 1431 event->fork.pid, event->fork.tid, 1432 event->fork.ppid, event->fork.ptid); 1433 } 1434 1435 int perf_event__process_fork(struct perf_tool *tool __maybe_unused, 1436 union perf_event *event, 1437 struct perf_sample *sample, 1438 struct machine *machine) 1439 { 1440 return machine__process_fork_event(machine, event, sample); 1441 } 1442 1443 int perf_event__process_exit(struct perf_tool *tool __maybe_unused, 1444 union perf_event *event, 1445 struct perf_sample *sample, 1446 struct machine *machine) 1447 { 1448 return machine__process_exit_event(machine, event, sample); 1449 } 1450 1451 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp) 1452 { 1453 return fprintf(fp, " offset: %#"PRI_lx64" size: %#"PRI_lx64" flags: %#"PRI_lx64" [%s%s%s]\n", 1454 event->aux.aux_offset, event->aux.aux_size, 1455 event->aux.flags, 1456 event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "", 1457 event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "", 1458 event->aux.flags & PERF_AUX_FLAG_PARTIAL ? "P" : ""); 1459 } 1460 1461 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp) 1462 { 1463 return fprintf(fp, " pid: %u tid: %u\n", 1464 event->itrace_start.pid, event->itrace_start.tid); 1465 } 1466 1467 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp) 1468 { 1469 bool out = event->header.misc & PERF_RECORD_MISC_SWITCH_OUT; 1470 const char *in_out = !out ? "IN " : 1471 !(event->header.misc & PERF_RECORD_MISC_SWITCH_OUT_PREEMPT) ? 1472 "OUT " : "OUT preempt"; 1473 1474 if (event->header.type == PERF_RECORD_SWITCH) 1475 return fprintf(fp, " %s\n", in_out); 1476 1477 return fprintf(fp, " %s %s pid/tid: %5u/%-5u\n", 1478 in_out, out ? "next" : "prev", 1479 event->context_switch.next_prev_pid, 1480 event->context_switch.next_prev_tid); 1481 } 1482 1483 static size_t perf_event__fprintf_lost(union perf_event *event, FILE *fp) 1484 { 1485 return fprintf(fp, " lost %" PRI_lu64 "\n", event->lost.lost); 1486 } 1487 1488 size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp) 1489 { 1490 return fprintf(fp, " addr %" PRI_lx64 " len %u type %u flags 0x%x name %s\n", 1491 event->ksymbol.addr, event->ksymbol.len, 1492 event->ksymbol.ksym_type, 1493 event->ksymbol.flags, event->ksymbol.name); 1494 } 1495 1496 size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp) 1497 { 1498 return fprintf(fp, " type %u, flags %u, id %u\n", 1499 event->bpf.type, event->bpf.flags, event->bpf.id); 1500 } 1501 1502 size_t perf_event__fprintf(union perf_event *event, FILE *fp) 1503 { 1504 size_t ret = fprintf(fp, "PERF_RECORD_%s", 1505 perf_event__name(event->header.type)); 1506 1507 switch (event->header.type) { 1508 case PERF_RECORD_COMM: 1509 ret += perf_event__fprintf_comm(event, fp); 1510 break; 1511 case PERF_RECORD_FORK: 1512 case PERF_RECORD_EXIT: 1513 ret += perf_event__fprintf_task(event, fp); 1514 break; 1515 case PERF_RECORD_MMAP: 1516 ret += perf_event__fprintf_mmap(event, fp); 1517 break; 1518 case PERF_RECORD_NAMESPACES: 1519 ret += perf_event__fprintf_namespaces(event, fp); 1520 break; 1521 case PERF_RECORD_MMAP2: 1522 ret += perf_event__fprintf_mmap2(event, fp); 1523 break; 1524 case PERF_RECORD_AUX: 1525 ret += perf_event__fprintf_aux(event, fp); 1526 break; 1527 case PERF_RECORD_ITRACE_START: 1528 ret += perf_event__fprintf_itrace_start(event, fp); 1529 break; 1530 case PERF_RECORD_SWITCH: 1531 case PERF_RECORD_SWITCH_CPU_WIDE: 1532 ret += perf_event__fprintf_switch(event, fp); 1533 break; 1534 case PERF_RECORD_LOST: 1535 ret += perf_event__fprintf_lost(event, fp); 1536 break; 1537 case PERF_RECORD_KSYMBOL: 1538 ret += perf_event__fprintf_ksymbol(event, fp); 1539 break; 1540 case PERF_RECORD_BPF_EVENT: 1541 ret += perf_event__fprintf_bpf(event, fp); 1542 break; 1543 default: 1544 ret += fprintf(fp, "\n"); 1545 } 1546 1547 return ret; 1548 } 1549 1550 int perf_event__process(struct perf_tool *tool __maybe_unused, 1551 union perf_event *event, 1552 struct perf_sample *sample, 1553 struct machine *machine) 1554 { 1555 return machine__process_event(machine, event, sample); 1556 } 1557 1558 struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, 1559 struct addr_location *al) 1560 { 1561 struct map_groups *mg = thread->mg; 1562 struct machine *machine = mg->machine; 1563 bool load_map = false; 1564 1565 al->machine = machine; 1566 al->thread = thread; 1567 al->addr = addr; 1568 al->cpumode = cpumode; 1569 al->filtered = 0; 1570 1571 if (machine == NULL) { 1572 al->map = NULL; 1573 return NULL; 1574 } 1575 1576 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { 1577 al->level = 'k'; 1578 mg = &machine->kmaps; 1579 load_map = true; 1580 } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { 1581 al->level = '.'; 1582 } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { 1583 al->level = 'g'; 1584 mg = &machine->kmaps; 1585 load_map = true; 1586 } else if (cpumode == PERF_RECORD_MISC_GUEST_USER && perf_guest) { 1587 al->level = 'u'; 1588 } else { 1589 al->level = 'H'; 1590 al->map = NULL; 1591 1592 if ((cpumode == PERF_RECORD_MISC_GUEST_USER || 1593 cpumode == PERF_RECORD_MISC_GUEST_KERNEL) && 1594 !perf_guest) 1595 al->filtered |= (1 << HIST_FILTER__GUEST); 1596 if ((cpumode == PERF_RECORD_MISC_USER || 1597 cpumode == PERF_RECORD_MISC_KERNEL) && 1598 !perf_host) 1599 al->filtered |= (1 << HIST_FILTER__HOST); 1600 1601 return NULL; 1602 } 1603 1604 al->map = map_groups__find(mg, al->addr); 1605 if (al->map != NULL) { 1606 /* 1607 * Kernel maps might be changed when loading symbols so loading 1608 * must be done prior to using kernel maps. 1609 */ 1610 if (load_map) 1611 map__load(al->map); 1612 al->addr = al->map->map_ip(al->map, al->addr); 1613 } 1614 1615 return al->map; 1616 } 1617 1618 /* 1619 * For branch stacks or branch samples, the sample cpumode might not be correct 1620 * because it applies only to the sample 'ip' and not necessary to 'addr' or 1621 * branch stack addresses. If possible, use a fallback to deal with those cases. 1622 */ 1623 struct map *thread__find_map_fb(struct thread *thread, u8 cpumode, u64 addr, 1624 struct addr_location *al) 1625 { 1626 struct map *map = thread__find_map(thread, cpumode, addr, al); 1627 struct machine *machine = thread->mg->machine; 1628 u8 addr_cpumode = machine__addr_cpumode(machine, cpumode, addr); 1629 1630 if (map || addr_cpumode == cpumode) 1631 return map; 1632 1633 return thread__find_map(thread, addr_cpumode, addr, al); 1634 } 1635 1636 struct symbol *thread__find_symbol(struct thread *thread, u8 cpumode, 1637 u64 addr, struct addr_location *al) 1638 { 1639 al->sym = NULL; 1640 if (thread__find_map(thread, cpumode, addr, al)) 1641 al->sym = map__find_symbol(al->map, al->addr); 1642 return al->sym; 1643 } 1644 1645 struct symbol *thread__find_symbol_fb(struct thread *thread, u8 cpumode, 1646 u64 addr, struct addr_location *al) 1647 { 1648 al->sym = NULL; 1649 if (thread__find_map_fb(thread, cpumode, addr, al)) 1650 al->sym = map__find_symbol(al->map, al->addr); 1651 return al->sym; 1652 } 1653 1654 /* 1655 * Callers need to drop the reference to al->thread, obtained in 1656 * machine__findnew_thread() 1657 */ 1658 int machine__resolve(struct machine *machine, struct addr_location *al, 1659 struct perf_sample *sample) 1660 { 1661 struct thread *thread = machine__findnew_thread(machine, sample->pid, 1662 sample->tid); 1663 1664 if (thread == NULL) 1665 return -1; 1666 1667 dump_printf(" ... thread: %s:%d\n", thread__comm_str(thread), thread->tid); 1668 thread__find_map(thread, sample->cpumode, sample->ip, al); 1669 dump_printf(" ...... dso: %s\n", 1670 al->map ? al->map->dso->long_name : 1671 al->level == 'H' ? "[hypervisor]" : "<not found>"); 1672 1673 if (thread__is_filtered(thread)) 1674 al->filtered |= (1 << HIST_FILTER__THREAD); 1675 1676 al->sym = NULL; 1677 al->cpu = sample->cpu; 1678 al->socket = -1; 1679 al->srcline = NULL; 1680 1681 if (al->cpu >= 0) { 1682 struct perf_env *env = machine->env; 1683 1684 if (env && env->cpu) 1685 al->socket = env->cpu[al->cpu].socket_id; 1686 } 1687 1688 if (al->map) { 1689 struct dso *dso = al->map->dso; 1690 1691 if (symbol_conf.dso_list && 1692 (!dso || !(strlist__has_entry(symbol_conf.dso_list, 1693 dso->short_name) || 1694 (dso->short_name != dso->long_name && 1695 strlist__has_entry(symbol_conf.dso_list, 1696 dso->long_name))))) { 1697 al->filtered |= (1 << HIST_FILTER__DSO); 1698 } 1699 1700 al->sym = map__find_symbol(al->map, al->addr); 1701 } 1702 1703 if (symbol_conf.sym_list && 1704 (!al->sym || !strlist__has_entry(symbol_conf.sym_list, 1705 al->sym->name))) { 1706 al->filtered |= (1 << HIST_FILTER__SYMBOL); 1707 } 1708 1709 return 0; 1710 } 1711 1712 /* 1713 * The preprocess_sample method will return with reference counts for the 1714 * in it, when done using (and perhaps getting ref counts if needing to 1715 * keep a pointer to one of those entries) it must be paired with 1716 * addr_location__put(), so that the refcounts can be decremented. 1717 */ 1718 void addr_location__put(struct addr_location *al) 1719 { 1720 thread__zput(al->thread); 1721 } 1722 1723 bool is_bts_event(struct perf_event_attr *attr) 1724 { 1725 return attr->type == PERF_TYPE_HARDWARE && 1726 (attr->config & PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && 1727 attr->sample_period == 1; 1728 } 1729 1730 bool sample_addr_correlates_sym(struct perf_event_attr *attr) 1731 { 1732 if (attr->type == PERF_TYPE_SOFTWARE && 1733 (attr->config == PERF_COUNT_SW_PAGE_FAULTS || 1734 attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN || 1735 attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)) 1736 return true; 1737 1738 if (is_bts_event(attr)) 1739 return true; 1740 1741 return false; 1742 } 1743 1744 void thread__resolve(struct thread *thread, struct addr_location *al, 1745 struct perf_sample *sample) 1746 { 1747 thread__find_map_fb(thread, sample->cpumode, sample->addr, al); 1748 1749 al->cpu = sample->cpu; 1750 al->sym = NULL; 1751 1752 if (al->map) 1753 al->sym = map__find_symbol(al->map, al->addr); 1754 } 1755