1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include "util/cgroup.h" 4 #include "util/data.h" 5 #include "util/debug.h" 6 #include "util/dso.h" 7 #include "util/event.h" 8 #include "util/evlist.h" 9 #include "util/machine.h" 10 #include "util/map.h" 11 #include "util/map_symbol.h" 12 #include "util/branch.h" 13 #include "util/memswap.h" 14 #include "util/namespaces.h" 15 #include "util/session.h" 16 #include "util/stat.h" 17 #include "util/symbol.h" 18 #include "util/synthetic-events.h" 19 #include "util/target.h" 20 #include "util/time-utils.h" 21 #include <linux/bitops.h> 22 #include <linux/kernel.h> 23 #include <linux/string.h> 24 #include <linux/zalloc.h> 25 #include <linux/perf_event.h> 26 #include <asm/bug.h> 27 #include <perf/evsel.h> 28 #include <perf/cpumap.h> 29 #include <internal/lib.h> // page_size 30 #include <internal/threadmap.h> 31 #include <perf/threadmap.h> 32 #include <symbol/kallsyms.h> 33 #include <dirent.h> 34 #include <errno.h> 35 #include <inttypes.h> 36 #include <stdio.h> 37 #include <string.h> 38 #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ 39 #include <api/fs/fs.h> 40 #include <api/io.h> 41 #include <sys/types.h> 42 #include <sys/stat.h> 43 #include <fcntl.h> 44 #include <unistd.h> 45 46 #define DEFAULT_PROC_MAP_PARSE_TIMEOUT 500 47 48 unsigned int proc_map_timeout = DEFAULT_PROC_MAP_PARSE_TIMEOUT; 49 50 int perf_tool__process_synth_event(struct perf_tool *tool, 51 union perf_event *event, 52 struct machine *machine, 53 perf_event__handler_t process) 54 { 55 struct perf_sample synth_sample = { 56 .pid = -1, 57 .tid = -1, 58 .time = -1, 59 .stream_id = -1, 60 .cpu = -1, 61 .period = 1, 62 .cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK, 63 }; 64 65 return process(tool, event, &synth_sample, machine); 66 }; 67 68 /* 69 * Assumes that the first 4095 bytes of /proc/pid/stat contains 70 * the comm, tgid and ppid. 71 */ 72 static int perf_event__get_comm_ids(pid_t pid, pid_t tid, char *comm, size_t len, 73 pid_t *tgid, pid_t *ppid, bool *kernel) 74 { 75 char bf[4096]; 76 int fd; 77 size_t size = 0; 78 ssize_t n; 79 char *name, *tgids, *ppids, *vmpeak, *threads; 80 81 *tgid = -1; 82 *ppid = -1; 83 84 if (pid) 85 snprintf(bf, sizeof(bf), "/proc/%d/task/%d/status", pid, tid); 86 else 87 snprintf(bf, sizeof(bf), "/proc/%d/status", tid); 88 89 fd = open(bf, O_RDONLY); 90 if (fd < 0) { 91 pr_debug("couldn't open %s\n", bf); 92 return -1; 93 } 94 95 n = read(fd, bf, sizeof(bf) - 1); 96 close(fd); 97 if (n <= 0) { 98 pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", 99 tid); 100 return -1; 101 } 102 bf[n] = '\0'; 103 104 name = strstr(bf, "Name:"); 105 tgids = strstr(name ?: bf, "Tgid:"); 106 ppids = strstr(tgids ?: bf, "PPid:"); 107 vmpeak = strstr(ppids ?: bf, "VmPeak:"); 108 109 if (vmpeak) 110 threads = NULL; 111 else 112 threads = strstr(ppids ?: bf, "Threads:"); 113 114 if (name) { 115 char *nl; 116 117 name = skip_spaces(name + 5); /* strlen("Name:") */ 118 nl = strchr(name, '\n'); 119 if (nl) 120 *nl = '\0'; 121 122 size = strlen(name); 123 if (size >= len) 124 size = len - 1; 125 memcpy(comm, name, size); 126 comm[size] = '\0'; 127 } else { 128 pr_debug("Name: string not found for pid %d\n", tid); 129 } 130 131 if (tgids) { 132 tgids += 5; /* strlen("Tgid:") */ 133 *tgid = atoi(tgids); 134 } else { 135 pr_debug("Tgid: string not found for pid %d\n", tid); 136 } 137 138 if (ppids) { 139 ppids += 5; /* strlen("PPid:") */ 140 *ppid = atoi(ppids); 141 } else { 142 pr_debug("PPid: string not found for pid %d\n", tid); 143 } 144 145 if (!vmpeak && threads) 146 *kernel = true; 147 else 148 *kernel = false; 149 150 return 0; 151 } 152 153 static int perf_event__prepare_comm(union perf_event *event, pid_t pid, pid_t tid, 154 struct machine *machine, 155 pid_t *tgid, pid_t *ppid, bool *kernel) 156 { 157 size_t size; 158 159 *ppid = -1; 160 161 memset(&event->comm, 0, sizeof(event->comm)); 162 163 if (machine__is_host(machine)) { 164 if (perf_event__get_comm_ids(pid, tid, event->comm.comm, 165 sizeof(event->comm.comm), 166 tgid, ppid, kernel) != 0) { 167 return -1; 168 } 169 } else { 170 *tgid = machine->pid; 171 } 172 173 if (*tgid < 0) 174 return -1; 175 176 event->comm.pid = *tgid; 177 event->comm.header.type = PERF_RECORD_COMM; 178 179 size = strlen(event->comm.comm) + 1; 180 size = PERF_ALIGN(size, sizeof(u64)); 181 memset(event->comm.comm + size, 0, machine->id_hdr_size); 182 event->comm.header.size = (sizeof(event->comm) - 183 (sizeof(event->comm.comm) - size) + 184 machine->id_hdr_size); 185 event->comm.tid = tid; 186 187 return 0; 188 } 189 190 pid_t perf_event__synthesize_comm(struct perf_tool *tool, 191 union perf_event *event, pid_t pid, 192 perf_event__handler_t process, 193 struct machine *machine) 194 { 195 pid_t tgid, ppid; 196 bool kernel_thread; 197 198 if (perf_event__prepare_comm(event, 0, pid, machine, &tgid, &ppid, 199 &kernel_thread) != 0) 200 return -1; 201 202 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) 203 return -1; 204 205 return tgid; 206 } 207 208 static void perf_event__get_ns_link_info(pid_t pid, const char *ns, 209 struct perf_ns_link_info *ns_link_info) 210 { 211 struct stat64 st; 212 char proc_ns[128]; 213 214 sprintf(proc_ns, "/proc/%u/ns/%s", pid, ns); 215 if (stat64(proc_ns, &st) == 0) { 216 ns_link_info->dev = st.st_dev; 217 ns_link_info->ino = st.st_ino; 218 } 219 } 220 221 int perf_event__synthesize_namespaces(struct perf_tool *tool, 222 union perf_event *event, 223 pid_t pid, pid_t tgid, 224 perf_event__handler_t process, 225 struct machine *machine) 226 { 227 u32 idx; 228 struct perf_ns_link_info *ns_link_info; 229 230 if (!tool || !tool->namespace_events) 231 return 0; 232 233 memset(&event->namespaces, 0, (sizeof(event->namespaces) + 234 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 235 machine->id_hdr_size)); 236 237 event->namespaces.pid = tgid; 238 event->namespaces.tid = pid; 239 240 event->namespaces.nr_namespaces = NR_NAMESPACES; 241 242 ns_link_info = event->namespaces.link_info; 243 244 for (idx = 0; idx < event->namespaces.nr_namespaces; idx++) 245 perf_event__get_ns_link_info(pid, perf_ns__name(idx), 246 &ns_link_info[idx]); 247 248 event->namespaces.header.type = PERF_RECORD_NAMESPACES; 249 250 event->namespaces.header.size = (sizeof(event->namespaces) + 251 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 252 machine->id_hdr_size); 253 254 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) 255 return -1; 256 257 return 0; 258 } 259 260 static int perf_event__synthesize_fork(struct perf_tool *tool, 261 union perf_event *event, 262 pid_t pid, pid_t tgid, pid_t ppid, 263 perf_event__handler_t process, 264 struct machine *machine) 265 { 266 memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); 267 268 /* 269 * for main thread set parent to ppid from status file. For other 270 * threads set parent pid to main thread. ie., assume main thread 271 * spawns all threads in a process 272 */ 273 if (tgid == pid) { 274 event->fork.ppid = ppid; 275 event->fork.ptid = ppid; 276 } else { 277 event->fork.ppid = tgid; 278 event->fork.ptid = tgid; 279 } 280 event->fork.pid = tgid; 281 event->fork.tid = pid; 282 event->fork.header.type = PERF_RECORD_FORK; 283 event->fork.header.misc = PERF_RECORD_MISC_FORK_EXEC; 284 285 event->fork.header.size = (sizeof(event->fork) + machine->id_hdr_size); 286 287 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) 288 return -1; 289 290 return 0; 291 } 292 293 static bool read_proc_maps_line(struct io *io, __u64 *start, __u64 *end, 294 u32 *prot, u32 *flags, __u64 *offset, 295 u32 *maj, u32 *min, 296 __u64 *inode, 297 ssize_t pathname_size, char *pathname) 298 { 299 __u64 temp; 300 int ch; 301 char *start_pathname = pathname; 302 303 if (io__get_hex(io, start) != '-') 304 return false; 305 if (io__get_hex(io, end) != ' ') 306 return false; 307 308 /* map protection and flags bits */ 309 *prot = 0; 310 ch = io__get_char(io); 311 if (ch == 'r') 312 *prot |= PROT_READ; 313 else if (ch != '-') 314 return false; 315 ch = io__get_char(io); 316 if (ch == 'w') 317 *prot |= PROT_WRITE; 318 else if (ch != '-') 319 return false; 320 ch = io__get_char(io); 321 if (ch == 'x') 322 *prot |= PROT_EXEC; 323 else if (ch != '-') 324 return false; 325 ch = io__get_char(io); 326 if (ch == 's') 327 *flags = MAP_SHARED; 328 else if (ch == 'p') 329 *flags = MAP_PRIVATE; 330 else 331 return false; 332 if (io__get_char(io) != ' ') 333 return false; 334 335 if (io__get_hex(io, offset) != ' ') 336 return false; 337 338 if (io__get_hex(io, &temp) != ':') 339 return false; 340 *maj = temp; 341 if (io__get_hex(io, &temp) != ' ') 342 return false; 343 *min = temp; 344 345 ch = io__get_dec(io, inode); 346 if (ch != ' ') { 347 *pathname = '\0'; 348 return ch == '\n'; 349 } 350 do { 351 ch = io__get_char(io); 352 } while (ch == ' '); 353 while (true) { 354 if (ch < 0) 355 return false; 356 if (ch == '\0' || ch == '\n' || 357 (pathname + 1 - start_pathname) >= pathname_size) { 358 *pathname = '\0'; 359 return true; 360 } 361 *pathname++ = ch; 362 ch = io__get_char(io); 363 } 364 } 365 366 static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event, 367 bool is_kernel) 368 { 369 struct build_id bid; 370 struct nsinfo *nsi; 371 struct nscookie nc; 372 int rc; 373 374 if (is_kernel) { 375 rc = sysfs__read_build_id("/sys/kernel/notes", &bid); 376 goto out; 377 } 378 379 nsi = nsinfo__new(event->pid); 380 nsinfo__mountns_enter(nsi, &nc); 381 382 rc = filename__read_build_id(event->filename, &bid) > 0 ? 0 : -1; 383 384 nsinfo__mountns_exit(&nc); 385 nsinfo__put(nsi); 386 387 out: 388 if (rc == 0) { 389 memcpy(event->build_id, bid.data, sizeof(bid.data)); 390 event->build_id_size = (u8) bid.size; 391 event->header.misc |= PERF_RECORD_MISC_MMAP_BUILD_ID; 392 event->__reserved_1 = 0; 393 event->__reserved_2 = 0; 394 } else { 395 if (event->filename[0] == '/') { 396 pr_debug2("Failed to read build ID for %s\n", 397 event->filename); 398 } 399 } 400 } 401 402 int perf_event__synthesize_mmap_events(struct perf_tool *tool, 403 union perf_event *event, 404 pid_t pid, pid_t tgid, 405 perf_event__handler_t process, 406 struct machine *machine, 407 bool mmap_data) 408 { 409 unsigned long long t; 410 char bf[BUFSIZ]; 411 struct io io; 412 bool truncation = false; 413 unsigned long long timeout = proc_map_timeout * 1000000ULL; 414 int rc = 0; 415 const char *hugetlbfs_mnt = hugetlbfs__mountpoint(); 416 int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0; 417 418 if (machine__is_default_guest(machine)) 419 return 0; 420 421 snprintf(bf, sizeof(bf), "%s/proc/%d/task/%d/maps", 422 machine->root_dir, pid, pid); 423 424 io.fd = open(bf, O_RDONLY, 0); 425 if (io.fd < 0) { 426 /* 427 * We raced with a task exiting - just return: 428 */ 429 pr_debug("couldn't open %s\n", bf); 430 return -1; 431 } 432 io__init(&io, io.fd, bf, sizeof(bf)); 433 434 event->header.type = PERF_RECORD_MMAP2; 435 t = rdclock(); 436 437 while (!io.eof) { 438 static const char anonstr[] = "//anon"; 439 size_t size, aligned_size; 440 441 /* ensure null termination since stack will be reused. */ 442 event->mmap2.filename[0] = '\0'; 443 444 /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ 445 if (!read_proc_maps_line(&io, 446 &event->mmap2.start, 447 &event->mmap2.len, 448 &event->mmap2.prot, 449 &event->mmap2.flags, 450 &event->mmap2.pgoff, 451 &event->mmap2.maj, 452 &event->mmap2.min, 453 &event->mmap2.ino, 454 sizeof(event->mmap2.filename), 455 event->mmap2.filename)) 456 continue; 457 458 if ((rdclock() - t) > timeout) { 459 pr_warning("Reading %s/proc/%d/task/%d/maps time out. " 460 "You may want to increase " 461 "the time limit by --proc-map-timeout\n", 462 machine->root_dir, pid, pid); 463 truncation = true; 464 goto out; 465 } 466 467 event->mmap2.ino_generation = 0; 468 469 /* 470 * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c 471 */ 472 if (machine__is_host(machine)) 473 event->header.misc = PERF_RECORD_MISC_USER; 474 else 475 event->header.misc = PERF_RECORD_MISC_GUEST_USER; 476 477 if ((event->mmap2.prot & PROT_EXEC) == 0) { 478 if (!mmap_data || (event->mmap2.prot & PROT_READ) == 0) 479 continue; 480 481 event->header.misc |= PERF_RECORD_MISC_MMAP_DATA; 482 } 483 484 out: 485 if (truncation) 486 event->header.misc |= PERF_RECORD_MISC_PROC_MAP_PARSE_TIMEOUT; 487 488 if (!strcmp(event->mmap2.filename, "")) 489 strcpy(event->mmap2.filename, anonstr); 490 491 if (hugetlbfs_mnt_len && 492 !strncmp(event->mmap2.filename, hugetlbfs_mnt, 493 hugetlbfs_mnt_len)) { 494 strcpy(event->mmap2.filename, anonstr); 495 event->mmap2.flags |= MAP_HUGETLB; 496 } 497 498 size = strlen(event->mmap2.filename) + 1; 499 aligned_size = PERF_ALIGN(size, sizeof(u64)); 500 event->mmap2.len -= event->mmap.start; 501 event->mmap2.header.size = (sizeof(event->mmap2) - 502 (sizeof(event->mmap2.filename) - aligned_size)); 503 memset(event->mmap2.filename + size, 0, machine->id_hdr_size + 504 (aligned_size - size)); 505 event->mmap2.header.size += machine->id_hdr_size; 506 event->mmap2.pid = tgid; 507 event->mmap2.tid = pid; 508 509 if (symbol_conf.buildid_mmap2) 510 perf_record_mmap2__read_build_id(&event->mmap2, false); 511 512 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { 513 rc = -1; 514 break; 515 } 516 517 if (truncation) 518 break; 519 } 520 521 close(io.fd); 522 return rc; 523 } 524 525 #ifdef HAVE_FILE_HANDLE 526 static int perf_event__synthesize_cgroup(struct perf_tool *tool, 527 union perf_event *event, 528 char *path, size_t mount_len, 529 perf_event__handler_t process, 530 struct machine *machine) 531 { 532 size_t event_size = sizeof(event->cgroup) - sizeof(event->cgroup.path); 533 size_t path_len = strlen(path) - mount_len + 1; 534 struct { 535 struct file_handle fh; 536 uint64_t cgroup_id; 537 } handle; 538 int mount_id; 539 540 while (path_len % sizeof(u64)) 541 path[mount_len + path_len++] = '\0'; 542 543 memset(&event->cgroup, 0, event_size); 544 545 event->cgroup.header.type = PERF_RECORD_CGROUP; 546 event->cgroup.header.size = event_size + path_len + machine->id_hdr_size; 547 548 handle.fh.handle_bytes = sizeof(handle.cgroup_id); 549 if (name_to_handle_at(AT_FDCWD, path, &handle.fh, &mount_id, 0) < 0) { 550 pr_debug("stat failed: %s\n", path); 551 return -1; 552 } 553 554 event->cgroup.id = handle.cgroup_id; 555 strncpy(event->cgroup.path, path + mount_len, path_len); 556 memset(event->cgroup.path + path_len, 0, machine->id_hdr_size); 557 558 if (perf_tool__process_synth_event(tool, event, machine, process) < 0) { 559 pr_debug("process synth event failed\n"); 560 return -1; 561 } 562 563 return 0; 564 } 565 566 static int perf_event__walk_cgroup_tree(struct perf_tool *tool, 567 union perf_event *event, 568 char *path, size_t mount_len, 569 perf_event__handler_t process, 570 struct machine *machine) 571 { 572 size_t pos = strlen(path); 573 DIR *d; 574 struct dirent *dent; 575 int ret = 0; 576 577 if (perf_event__synthesize_cgroup(tool, event, path, mount_len, 578 process, machine) < 0) 579 return -1; 580 581 d = opendir(path); 582 if (d == NULL) { 583 pr_debug("failed to open directory: %s\n", path); 584 return -1; 585 } 586 587 while ((dent = readdir(d)) != NULL) { 588 if (dent->d_type != DT_DIR) 589 continue; 590 if (!strcmp(dent->d_name, ".") || 591 !strcmp(dent->d_name, "..")) 592 continue; 593 594 /* any sane path should be less than PATH_MAX */ 595 if (strlen(path) + strlen(dent->d_name) + 1 >= PATH_MAX) 596 continue; 597 598 if (path[pos - 1] != '/') 599 strcat(path, "/"); 600 strcat(path, dent->d_name); 601 602 ret = perf_event__walk_cgroup_tree(tool, event, path, 603 mount_len, process, machine); 604 if (ret < 0) 605 break; 606 607 path[pos] = '\0'; 608 } 609 610 closedir(d); 611 return ret; 612 } 613 614 int perf_event__synthesize_cgroups(struct perf_tool *tool, 615 perf_event__handler_t process, 616 struct machine *machine) 617 { 618 union perf_event event; 619 char cgrp_root[PATH_MAX]; 620 size_t mount_len; /* length of mount point in the path */ 621 622 if (!tool || !tool->cgroup_events) 623 return 0; 624 625 if (cgroupfs_find_mountpoint(cgrp_root, PATH_MAX, "perf_event") < 0) { 626 pr_debug("cannot find cgroup mount point\n"); 627 return -1; 628 } 629 630 mount_len = strlen(cgrp_root); 631 /* make sure the path starts with a slash (after mount point) */ 632 strcat(cgrp_root, "/"); 633 634 if (perf_event__walk_cgroup_tree(tool, &event, cgrp_root, mount_len, 635 process, machine) < 0) 636 return -1; 637 638 return 0; 639 } 640 #else 641 int perf_event__synthesize_cgroups(struct perf_tool *tool __maybe_unused, 642 perf_event__handler_t process __maybe_unused, 643 struct machine *machine __maybe_unused) 644 { 645 return -1; 646 } 647 #endif 648 649 int perf_event__synthesize_modules(struct perf_tool *tool, perf_event__handler_t process, 650 struct machine *machine) 651 { 652 int rc = 0; 653 struct map *pos; 654 struct maps *maps = machine__kernel_maps(machine); 655 union perf_event *event; 656 size_t size = symbol_conf.buildid_mmap2 ? 657 sizeof(event->mmap2) : sizeof(event->mmap); 658 659 event = zalloc(size + machine->id_hdr_size); 660 if (event == NULL) { 661 pr_debug("Not enough memory synthesizing mmap event " 662 "for kernel modules\n"); 663 return -1; 664 } 665 666 /* 667 * kernel uses 0 for user space maps, see kernel/perf_event.c 668 * __perf_event_mmap 669 */ 670 if (machine__is_host(machine)) 671 event->header.misc = PERF_RECORD_MISC_KERNEL; 672 else 673 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 674 675 maps__for_each_entry(maps, pos) { 676 if (!__map__is_kmodule(pos)) 677 continue; 678 679 if (symbol_conf.buildid_mmap2) { 680 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); 681 event->mmap2.header.type = PERF_RECORD_MMAP2; 682 event->mmap2.header.size = (sizeof(event->mmap2) - 683 (sizeof(event->mmap2.filename) - size)); 684 memset(event->mmap2.filename + size, 0, machine->id_hdr_size); 685 event->mmap2.header.size += machine->id_hdr_size; 686 event->mmap2.start = pos->start; 687 event->mmap2.len = pos->end - pos->start; 688 event->mmap2.pid = machine->pid; 689 690 memcpy(event->mmap2.filename, pos->dso->long_name, 691 pos->dso->long_name_len + 1); 692 693 perf_record_mmap2__read_build_id(&event->mmap2, false); 694 } else { 695 size = PERF_ALIGN(pos->dso->long_name_len + 1, sizeof(u64)); 696 event->mmap.header.type = PERF_RECORD_MMAP; 697 event->mmap.header.size = (sizeof(event->mmap) - 698 (sizeof(event->mmap.filename) - size)); 699 memset(event->mmap.filename + size, 0, machine->id_hdr_size); 700 event->mmap.header.size += machine->id_hdr_size; 701 event->mmap.start = pos->start; 702 event->mmap.len = pos->end - pos->start; 703 event->mmap.pid = machine->pid; 704 705 memcpy(event->mmap.filename, pos->dso->long_name, 706 pos->dso->long_name_len + 1); 707 } 708 709 if (perf_tool__process_synth_event(tool, event, machine, process) != 0) { 710 rc = -1; 711 break; 712 } 713 } 714 715 free(event); 716 return rc; 717 } 718 719 static int filter_task(const struct dirent *dirent) 720 { 721 return isdigit(dirent->d_name[0]); 722 } 723 724 static int __event__synthesize_thread(union perf_event *comm_event, 725 union perf_event *mmap_event, 726 union perf_event *fork_event, 727 union perf_event *namespaces_event, 728 pid_t pid, int full, perf_event__handler_t process, 729 struct perf_tool *tool, struct machine *machine, 730 bool needs_mmap, bool mmap_data) 731 { 732 char filename[PATH_MAX]; 733 struct dirent **dirent; 734 pid_t tgid, ppid; 735 int rc = 0; 736 int i, n; 737 738 /* special case: only send one comm event using passed in pid */ 739 if (!full) { 740 tgid = perf_event__synthesize_comm(tool, comm_event, pid, 741 process, machine); 742 743 if (tgid == -1) 744 return -1; 745 746 if (perf_event__synthesize_namespaces(tool, namespaces_event, pid, 747 tgid, process, machine) < 0) 748 return -1; 749 750 /* 751 * send mmap only for thread group leader 752 * see thread__init_maps() 753 */ 754 if (pid == tgid && needs_mmap && 755 perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 756 process, machine, mmap_data)) 757 return -1; 758 759 return 0; 760 } 761 762 if (machine__is_default_guest(machine)) 763 return 0; 764 765 snprintf(filename, sizeof(filename), "%s/proc/%d/task", 766 machine->root_dir, pid); 767 768 n = scandir(filename, &dirent, filter_task, NULL); 769 if (n < 0) 770 return n; 771 772 for (i = 0; i < n; i++) { 773 char *end; 774 pid_t _pid; 775 bool kernel_thread = false; 776 777 _pid = strtol(dirent[i]->d_name, &end, 10); 778 if (*end) 779 continue; 780 781 /* some threads may exit just after scan, ignore it */ 782 if (perf_event__prepare_comm(comm_event, pid, _pid, machine, 783 &tgid, &ppid, &kernel_thread) != 0) 784 continue; 785 786 rc = -1; 787 if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, 788 ppid, process, machine) < 0) 789 break; 790 791 if (perf_event__synthesize_namespaces(tool, namespaces_event, _pid, 792 tgid, process, machine) < 0) 793 break; 794 795 /* 796 * Send the prepared comm event 797 */ 798 if (perf_tool__process_synth_event(tool, comm_event, machine, process) != 0) 799 break; 800 801 rc = 0; 802 if (_pid == pid && !kernel_thread && needs_mmap) { 803 /* process the parent's maps too */ 804 rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, 805 process, machine, mmap_data); 806 if (rc) 807 break; 808 } 809 } 810 811 for (i = 0; i < n; i++) 812 zfree(&dirent[i]); 813 free(dirent); 814 815 return rc; 816 } 817 818 int perf_event__synthesize_thread_map(struct perf_tool *tool, 819 struct perf_thread_map *threads, 820 perf_event__handler_t process, 821 struct machine *machine, 822 bool needs_mmap, bool mmap_data) 823 { 824 union perf_event *comm_event, *mmap_event, *fork_event; 825 union perf_event *namespaces_event; 826 int err = -1, thread, j; 827 828 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 829 if (comm_event == NULL) 830 goto out; 831 832 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); 833 if (mmap_event == NULL) 834 goto out_free_comm; 835 836 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); 837 if (fork_event == NULL) 838 goto out_free_mmap; 839 840 namespaces_event = malloc(sizeof(namespaces_event->namespaces) + 841 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 842 machine->id_hdr_size); 843 if (namespaces_event == NULL) 844 goto out_free_fork; 845 846 err = 0; 847 for (thread = 0; thread < threads->nr; ++thread) { 848 if (__event__synthesize_thread(comm_event, mmap_event, 849 fork_event, namespaces_event, 850 perf_thread_map__pid(threads, thread), 0, 851 process, tool, machine, 852 needs_mmap, mmap_data)) { 853 err = -1; 854 break; 855 } 856 857 /* 858 * comm.pid is set to thread group id by 859 * perf_event__synthesize_comm 860 */ 861 if ((int) comm_event->comm.pid != perf_thread_map__pid(threads, thread)) { 862 bool need_leader = true; 863 864 /* is thread group leader in thread_map? */ 865 for (j = 0; j < threads->nr; ++j) { 866 if ((int) comm_event->comm.pid == perf_thread_map__pid(threads, j)) { 867 need_leader = false; 868 break; 869 } 870 } 871 872 /* if not, generate events for it */ 873 if (need_leader && 874 __event__synthesize_thread(comm_event, mmap_event, 875 fork_event, namespaces_event, 876 comm_event->comm.pid, 0, 877 process, tool, machine, 878 needs_mmap, mmap_data)) { 879 err = -1; 880 break; 881 } 882 } 883 } 884 free(namespaces_event); 885 out_free_fork: 886 free(fork_event); 887 out_free_mmap: 888 free(mmap_event); 889 out_free_comm: 890 free(comm_event); 891 out: 892 return err; 893 } 894 895 static int __perf_event__synthesize_threads(struct perf_tool *tool, 896 perf_event__handler_t process, 897 struct machine *machine, 898 bool needs_mmap, 899 bool mmap_data, 900 struct dirent **dirent, 901 int start, 902 int num) 903 { 904 union perf_event *comm_event, *mmap_event, *fork_event; 905 union perf_event *namespaces_event; 906 int err = -1; 907 char *end; 908 pid_t pid; 909 int i; 910 911 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); 912 if (comm_event == NULL) 913 goto out; 914 915 mmap_event = malloc(sizeof(mmap_event->mmap2) + machine->id_hdr_size); 916 if (mmap_event == NULL) 917 goto out_free_comm; 918 919 fork_event = malloc(sizeof(fork_event->fork) + machine->id_hdr_size); 920 if (fork_event == NULL) 921 goto out_free_mmap; 922 923 namespaces_event = malloc(sizeof(namespaces_event->namespaces) + 924 (NR_NAMESPACES * sizeof(struct perf_ns_link_info)) + 925 machine->id_hdr_size); 926 if (namespaces_event == NULL) 927 goto out_free_fork; 928 929 for (i = start; i < start + num; i++) { 930 if (!isdigit(dirent[i]->d_name[0])) 931 continue; 932 933 pid = (pid_t)strtol(dirent[i]->d_name, &end, 10); 934 /* only interested in proper numerical dirents */ 935 if (*end) 936 continue; 937 /* 938 * We may race with exiting thread, so don't stop just because 939 * one thread couldn't be synthesized. 940 */ 941 __event__synthesize_thread(comm_event, mmap_event, fork_event, 942 namespaces_event, pid, 1, process, 943 tool, machine, needs_mmap, mmap_data); 944 } 945 err = 0; 946 947 free(namespaces_event); 948 out_free_fork: 949 free(fork_event); 950 out_free_mmap: 951 free(mmap_event); 952 out_free_comm: 953 free(comm_event); 954 out: 955 return err; 956 } 957 958 struct synthesize_threads_arg { 959 struct perf_tool *tool; 960 perf_event__handler_t process; 961 struct machine *machine; 962 bool needs_mmap; 963 bool mmap_data; 964 struct dirent **dirent; 965 int num; 966 int start; 967 }; 968 969 static void *synthesize_threads_worker(void *arg) 970 { 971 struct synthesize_threads_arg *args = arg; 972 973 __perf_event__synthesize_threads(args->tool, args->process, 974 args->machine, 975 args->needs_mmap, args->mmap_data, 976 args->dirent, 977 args->start, args->num); 978 return NULL; 979 } 980 981 int perf_event__synthesize_threads(struct perf_tool *tool, 982 perf_event__handler_t process, 983 struct machine *machine, 984 bool needs_mmap, bool mmap_data, 985 unsigned int nr_threads_synthesize) 986 { 987 struct synthesize_threads_arg *args = NULL; 988 pthread_t *synthesize_threads = NULL; 989 char proc_path[PATH_MAX]; 990 struct dirent **dirent; 991 int num_per_thread; 992 int m, n, i, j; 993 int thread_nr; 994 int base = 0; 995 int err = -1; 996 997 998 if (machine__is_default_guest(machine)) 999 return 0; 1000 1001 snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); 1002 n = scandir(proc_path, &dirent, filter_task, NULL); 1003 if (n < 0) 1004 return err; 1005 1006 if (nr_threads_synthesize == UINT_MAX) 1007 thread_nr = sysconf(_SC_NPROCESSORS_ONLN); 1008 else 1009 thread_nr = nr_threads_synthesize; 1010 1011 if (thread_nr <= 1) { 1012 err = __perf_event__synthesize_threads(tool, process, 1013 machine, 1014 needs_mmap, mmap_data, 1015 dirent, base, n); 1016 goto free_dirent; 1017 } 1018 if (thread_nr > n) 1019 thread_nr = n; 1020 1021 synthesize_threads = calloc(sizeof(pthread_t), thread_nr); 1022 if (synthesize_threads == NULL) 1023 goto free_dirent; 1024 1025 args = calloc(sizeof(*args), thread_nr); 1026 if (args == NULL) 1027 goto free_threads; 1028 1029 num_per_thread = n / thread_nr; 1030 m = n % thread_nr; 1031 for (i = 0; i < thread_nr; i++) { 1032 args[i].tool = tool; 1033 args[i].process = process; 1034 args[i].machine = machine; 1035 args[i].needs_mmap = needs_mmap; 1036 args[i].mmap_data = mmap_data; 1037 args[i].dirent = dirent; 1038 } 1039 for (i = 0; i < m; i++) { 1040 args[i].num = num_per_thread + 1; 1041 args[i].start = i * args[i].num; 1042 } 1043 if (i != 0) 1044 base = args[i-1].start + args[i-1].num; 1045 for (j = i; j < thread_nr; j++) { 1046 args[j].num = num_per_thread; 1047 args[j].start = base + (j - i) * args[i].num; 1048 } 1049 1050 for (i = 0; i < thread_nr; i++) { 1051 if (pthread_create(&synthesize_threads[i], NULL, 1052 synthesize_threads_worker, &args[i])) 1053 goto out_join; 1054 } 1055 err = 0; 1056 out_join: 1057 for (i = 0; i < thread_nr; i++) 1058 pthread_join(synthesize_threads[i], NULL); 1059 free(args); 1060 free_threads: 1061 free(synthesize_threads); 1062 free_dirent: 1063 for (i = 0; i < n; i++) 1064 zfree(&dirent[i]); 1065 free(dirent); 1066 1067 return err; 1068 } 1069 1070 int __weak perf_event__synthesize_extra_kmaps(struct perf_tool *tool __maybe_unused, 1071 perf_event__handler_t process __maybe_unused, 1072 struct machine *machine __maybe_unused) 1073 { 1074 return 0; 1075 } 1076 1077 static int __perf_event__synthesize_kernel_mmap(struct perf_tool *tool, 1078 perf_event__handler_t process, 1079 struct machine *machine) 1080 { 1081 union perf_event *event; 1082 size_t size = symbol_conf.buildid_mmap2 ? 1083 sizeof(event->mmap2) : sizeof(event->mmap); 1084 struct map *map = machine__kernel_map(machine); 1085 struct kmap *kmap; 1086 int err; 1087 1088 if (map == NULL) 1089 return -1; 1090 1091 kmap = map__kmap(map); 1092 if (!kmap->ref_reloc_sym) 1093 return -1; 1094 1095 /* 1096 * We should get this from /sys/kernel/sections/.text, but till that is 1097 * available use this, and after it is use this as a fallback for older 1098 * kernels. 1099 */ 1100 event = zalloc(size + machine->id_hdr_size); 1101 if (event == NULL) { 1102 pr_debug("Not enough memory synthesizing mmap event " 1103 "for kernel modules\n"); 1104 return -1; 1105 } 1106 1107 if (machine__is_host(machine)) { 1108 /* 1109 * kernel uses PERF_RECORD_MISC_USER for user space maps, 1110 * see kernel/perf_event.c __perf_event_mmap 1111 */ 1112 event->header.misc = PERF_RECORD_MISC_KERNEL; 1113 } else { 1114 event->header.misc = PERF_RECORD_MISC_GUEST_KERNEL; 1115 } 1116 1117 if (symbol_conf.buildid_mmap2) { 1118 size = snprintf(event->mmap2.filename, sizeof(event->mmap2.filename), 1119 "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1; 1120 size = PERF_ALIGN(size, sizeof(u64)); 1121 event->mmap2.header.type = PERF_RECORD_MMAP2; 1122 event->mmap2.header.size = (sizeof(event->mmap2) - 1123 (sizeof(event->mmap2.filename) - size) + machine->id_hdr_size); 1124 event->mmap2.pgoff = kmap->ref_reloc_sym->addr; 1125 event->mmap2.start = map->start; 1126 event->mmap2.len = map->end - event->mmap.start; 1127 event->mmap2.pid = machine->pid; 1128 1129 perf_record_mmap2__read_build_id(&event->mmap2, true); 1130 } else { 1131 size = snprintf(event->mmap.filename, sizeof(event->mmap.filename), 1132 "%s%s", machine->mmap_name, kmap->ref_reloc_sym->name) + 1; 1133 size = PERF_ALIGN(size, sizeof(u64)); 1134 event->mmap.header.type = PERF_RECORD_MMAP; 1135 event->mmap.header.size = (sizeof(event->mmap) - 1136 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); 1137 event->mmap.pgoff = kmap->ref_reloc_sym->addr; 1138 event->mmap.start = map->start; 1139 event->mmap.len = map->end - event->mmap.start; 1140 event->mmap.pid = machine->pid; 1141 } 1142 1143 err = perf_tool__process_synth_event(tool, event, machine, process); 1144 free(event); 1145 1146 return err; 1147 } 1148 1149 int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, 1150 perf_event__handler_t process, 1151 struct machine *machine) 1152 { 1153 int err; 1154 1155 err = __perf_event__synthesize_kernel_mmap(tool, process, machine); 1156 if (err < 0) 1157 return err; 1158 1159 return perf_event__synthesize_extra_kmaps(tool, process, machine); 1160 } 1161 1162 int perf_event__synthesize_thread_map2(struct perf_tool *tool, 1163 struct perf_thread_map *threads, 1164 perf_event__handler_t process, 1165 struct machine *machine) 1166 { 1167 union perf_event *event; 1168 int i, err, size; 1169 1170 size = sizeof(event->thread_map); 1171 size += threads->nr * sizeof(event->thread_map.entries[0]); 1172 1173 event = zalloc(size); 1174 if (!event) 1175 return -ENOMEM; 1176 1177 event->header.type = PERF_RECORD_THREAD_MAP; 1178 event->header.size = size; 1179 event->thread_map.nr = threads->nr; 1180 1181 for (i = 0; i < threads->nr; i++) { 1182 struct perf_record_thread_map_entry *entry = &event->thread_map.entries[i]; 1183 char *comm = perf_thread_map__comm(threads, i); 1184 1185 if (!comm) 1186 comm = (char *) ""; 1187 1188 entry->pid = perf_thread_map__pid(threads, i); 1189 strncpy((char *) &entry->comm, comm, sizeof(entry->comm)); 1190 } 1191 1192 err = process(tool, event, NULL, machine); 1193 1194 free(event); 1195 return err; 1196 } 1197 1198 struct synthesize_cpu_map_data { 1199 const struct perf_cpu_map *map; 1200 int nr; 1201 int min_cpu; 1202 int max_cpu; 1203 int has_any_cpu; 1204 int type; 1205 size_t size; 1206 struct perf_record_cpu_map_data *data; 1207 }; 1208 1209 static void synthesize_cpus(struct synthesize_cpu_map_data *data) 1210 { 1211 data->data->type = PERF_CPU_MAP__CPUS; 1212 data->data->cpus_data.nr = data->nr; 1213 for (int i = 0; i < data->nr; i++) 1214 data->data->cpus_data.cpu[i] = perf_cpu_map__cpu(data->map, i).cpu; 1215 } 1216 1217 static void synthesize_mask(struct synthesize_cpu_map_data *data) 1218 { 1219 int idx; 1220 struct perf_cpu cpu; 1221 1222 /* Due to padding, the 4bytes per entry mask variant is always smaller. */ 1223 data->data->type = PERF_CPU_MAP__MASK; 1224 data->data->mask32_data.nr = BITS_TO_U32(data->max_cpu); 1225 data->data->mask32_data.long_size = 4; 1226 1227 perf_cpu_map__for_each_cpu(cpu, idx, data->map) { 1228 int bit_word = cpu.cpu / 32; 1229 u32 bit_mask = 1U << (cpu.cpu & 31); 1230 1231 data->data->mask32_data.mask[bit_word] |= bit_mask; 1232 } 1233 } 1234 1235 static void synthesize_range_cpus(struct synthesize_cpu_map_data *data) 1236 { 1237 data->data->type = PERF_CPU_MAP__RANGE_CPUS; 1238 data->data->range_cpu_data.any_cpu = data->has_any_cpu; 1239 data->data->range_cpu_data.start_cpu = data->min_cpu; 1240 data->data->range_cpu_data.end_cpu = data->max_cpu; 1241 } 1242 1243 static void *cpu_map_data__alloc(struct synthesize_cpu_map_data *syn_data, 1244 size_t header_size) 1245 { 1246 size_t size_cpus, size_mask; 1247 1248 syn_data->nr = perf_cpu_map__nr(syn_data->map); 1249 syn_data->has_any_cpu = (perf_cpu_map__cpu(syn_data->map, 0).cpu == -1) ? 1 : 0; 1250 1251 syn_data->min_cpu = perf_cpu_map__cpu(syn_data->map, syn_data->has_any_cpu).cpu; 1252 syn_data->max_cpu = perf_cpu_map__max(syn_data->map).cpu; 1253 if (syn_data->max_cpu - syn_data->min_cpu + 1 == syn_data->nr - syn_data->has_any_cpu) { 1254 /* A consecutive range of CPUs can be encoded using a range. */ 1255 assert(sizeof(u16) + sizeof(struct perf_record_range_cpu_map) == sizeof(u64)); 1256 syn_data->type = PERF_CPU_MAP__RANGE_CPUS; 1257 syn_data->size = header_size + sizeof(u64); 1258 return zalloc(syn_data->size); 1259 } 1260 1261 size_cpus = sizeof(u16) + sizeof(struct cpu_map_entries) + syn_data->nr * sizeof(u16); 1262 /* Due to padding, the 4bytes per entry mask variant is always smaller. */ 1263 size_mask = sizeof(u16) + sizeof(struct perf_record_mask_cpu_map32) + 1264 BITS_TO_U32(syn_data->max_cpu) * sizeof(__u32); 1265 if (syn_data->has_any_cpu || size_cpus < size_mask) { 1266 /* Follow the CPU map encoding. */ 1267 syn_data->type = PERF_CPU_MAP__CPUS; 1268 syn_data->size = header_size + PERF_ALIGN(size_cpus, sizeof(u64)); 1269 return zalloc(syn_data->size); 1270 } 1271 /* Encode using a bitmask. */ 1272 syn_data->type = PERF_CPU_MAP__MASK; 1273 syn_data->size = header_size + PERF_ALIGN(size_mask, sizeof(u64)); 1274 return zalloc(syn_data->size); 1275 } 1276 1277 static void cpu_map_data__synthesize(struct synthesize_cpu_map_data *data) 1278 { 1279 switch (data->type) { 1280 case PERF_CPU_MAP__CPUS: 1281 synthesize_cpus(data); 1282 break; 1283 case PERF_CPU_MAP__MASK: 1284 synthesize_mask(data); 1285 break; 1286 case PERF_CPU_MAP__RANGE_CPUS: 1287 synthesize_range_cpus(data); 1288 break; 1289 default: 1290 break; 1291 } 1292 } 1293 1294 static struct perf_record_cpu_map *cpu_map_event__new(const struct perf_cpu_map *map) 1295 { 1296 struct synthesize_cpu_map_data syn_data = { .map = map }; 1297 struct perf_record_cpu_map *event; 1298 1299 1300 event = cpu_map_data__alloc(&syn_data, sizeof(struct perf_event_header)); 1301 if (!event) 1302 return NULL; 1303 1304 syn_data.data = &event->data; 1305 event->header.type = PERF_RECORD_CPU_MAP; 1306 event->header.size = syn_data.size; 1307 cpu_map_data__synthesize(&syn_data); 1308 return event; 1309 } 1310 1311 1312 int perf_event__synthesize_cpu_map(struct perf_tool *tool, 1313 const struct perf_cpu_map *map, 1314 perf_event__handler_t process, 1315 struct machine *machine) 1316 { 1317 struct perf_record_cpu_map *event; 1318 int err; 1319 1320 event = cpu_map_event__new(map); 1321 if (!event) 1322 return -ENOMEM; 1323 1324 err = process(tool, (union perf_event *) event, NULL, machine); 1325 1326 free(event); 1327 return err; 1328 } 1329 1330 int perf_event__synthesize_stat_config(struct perf_tool *tool, 1331 struct perf_stat_config *config, 1332 perf_event__handler_t process, 1333 struct machine *machine) 1334 { 1335 struct perf_record_stat_config *event; 1336 int size, i = 0, err; 1337 1338 size = sizeof(*event); 1339 size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0])); 1340 1341 event = zalloc(size); 1342 if (!event) 1343 return -ENOMEM; 1344 1345 event->header.type = PERF_RECORD_STAT_CONFIG; 1346 event->header.size = size; 1347 event->nr = PERF_STAT_CONFIG_TERM__MAX; 1348 1349 #define ADD(__term, __val) \ 1350 event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term; \ 1351 event->data[i].val = __val; \ 1352 i++; 1353 1354 ADD(AGGR_MODE, config->aggr_mode) 1355 ADD(INTERVAL, config->interval) 1356 ADD(SCALE, config->scale) 1357 1358 WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX, 1359 "stat config terms unbalanced\n"); 1360 #undef ADD 1361 1362 err = process(tool, (union perf_event *) event, NULL, machine); 1363 1364 free(event); 1365 return err; 1366 } 1367 1368 int perf_event__synthesize_stat(struct perf_tool *tool, 1369 struct perf_cpu cpu, u32 thread, u64 id, 1370 struct perf_counts_values *count, 1371 perf_event__handler_t process, 1372 struct machine *machine) 1373 { 1374 struct perf_record_stat event; 1375 1376 event.header.type = PERF_RECORD_STAT; 1377 event.header.size = sizeof(event); 1378 event.header.misc = 0; 1379 1380 event.id = id; 1381 event.cpu = cpu.cpu; 1382 event.thread = thread; 1383 event.val = count->val; 1384 event.ena = count->ena; 1385 event.run = count->run; 1386 1387 return process(tool, (union perf_event *) &event, NULL, machine); 1388 } 1389 1390 int perf_event__synthesize_stat_round(struct perf_tool *tool, 1391 u64 evtime, u64 type, 1392 perf_event__handler_t process, 1393 struct machine *machine) 1394 { 1395 struct perf_record_stat_round event; 1396 1397 event.header.type = PERF_RECORD_STAT_ROUND; 1398 event.header.size = sizeof(event); 1399 event.header.misc = 0; 1400 1401 event.time = evtime; 1402 event.type = type; 1403 1404 return process(tool, (union perf_event *) &event, NULL, machine); 1405 } 1406 1407 size_t perf_event__sample_event_size(const struct perf_sample *sample, u64 type, u64 read_format) 1408 { 1409 size_t sz, result = sizeof(struct perf_record_sample); 1410 1411 if (type & PERF_SAMPLE_IDENTIFIER) 1412 result += sizeof(u64); 1413 1414 if (type & PERF_SAMPLE_IP) 1415 result += sizeof(u64); 1416 1417 if (type & PERF_SAMPLE_TID) 1418 result += sizeof(u64); 1419 1420 if (type & PERF_SAMPLE_TIME) 1421 result += sizeof(u64); 1422 1423 if (type & PERF_SAMPLE_ADDR) 1424 result += sizeof(u64); 1425 1426 if (type & PERF_SAMPLE_ID) 1427 result += sizeof(u64); 1428 1429 if (type & PERF_SAMPLE_STREAM_ID) 1430 result += sizeof(u64); 1431 1432 if (type & PERF_SAMPLE_CPU) 1433 result += sizeof(u64); 1434 1435 if (type & PERF_SAMPLE_PERIOD) 1436 result += sizeof(u64); 1437 1438 if (type & PERF_SAMPLE_READ) { 1439 result += sizeof(u64); 1440 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 1441 result += sizeof(u64); 1442 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 1443 result += sizeof(u64); 1444 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ 1445 if (read_format & PERF_FORMAT_GROUP) { 1446 sz = sample_read_value_size(read_format); 1447 result += sz * sample->read.group.nr; 1448 } else { 1449 result += sizeof(u64); 1450 if (read_format & PERF_FORMAT_LOST) 1451 result += sizeof(u64); 1452 } 1453 } 1454 1455 if (type & PERF_SAMPLE_CALLCHAIN) { 1456 sz = (sample->callchain->nr + 1) * sizeof(u64); 1457 result += sz; 1458 } 1459 1460 if (type & PERF_SAMPLE_RAW) { 1461 result += sizeof(u32); 1462 result += sample->raw_size; 1463 } 1464 1465 if (type & PERF_SAMPLE_BRANCH_STACK) { 1466 sz = sample->branch_stack->nr * sizeof(struct branch_entry); 1467 /* nr, hw_idx */ 1468 sz += 2 * sizeof(u64); 1469 result += sz; 1470 } 1471 1472 if (type & PERF_SAMPLE_REGS_USER) { 1473 if (sample->user_regs.abi) { 1474 result += sizeof(u64); 1475 sz = hweight64(sample->user_regs.mask) * sizeof(u64); 1476 result += sz; 1477 } else { 1478 result += sizeof(u64); 1479 } 1480 } 1481 1482 if (type & PERF_SAMPLE_STACK_USER) { 1483 sz = sample->user_stack.size; 1484 result += sizeof(u64); 1485 if (sz) { 1486 result += sz; 1487 result += sizeof(u64); 1488 } 1489 } 1490 1491 if (type & PERF_SAMPLE_WEIGHT_TYPE) 1492 result += sizeof(u64); 1493 1494 if (type & PERF_SAMPLE_DATA_SRC) 1495 result += sizeof(u64); 1496 1497 if (type & PERF_SAMPLE_TRANSACTION) 1498 result += sizeof(u64); 1499 1500 if (type & PERF_SAMPLE_REGS_INTR) { 1501 if (sample->intr_regs.abi) { 1502 result += sizeof(u64); 1503 sz = hweight64(sample->intr_regs.mask) * sizeof(u64); 1504 result += sz; 1505 } else { 1506 result += sizeof(u64); 1507 } 1508 } 1509 1510 if (type & PERF_SAMPLE_PHYS_ADDR) 1511 result += sizeof(u64); 1512 1513 if (type & PERF_SAMPLE_CGROUP) 1514 result += sizeof(u64); 1515 1516 if (type & PERF_SAMPLE_DATA_PAGE_SIZE) 1517 result += sizeof(u64); 1518 1519 if (type & PERF_SAMPLE_CODE_PAGE_SIZE) 1520 result += sizeof(u64); 1521 1522 if (type & PERF_SAMPLE_AUX) { 1523 result += sizeof(u64); 1524 result += sample->aux_sample.size; 1525 } 1526 1527 return result; 1528 } 1529 1530 void __weak arch_perf_synthesize_sample_weight(const struct perf_sample *data, 1531 __u64 *array, u64 type __maybe_unused) 1532 { 1533 *array = data->weight; 1534 } 1535 1536 static __u64 *copy_read_group_values(__u64 *array, __u64 read_format, 1537 const struct perf_sample *sample) 1538 { 1539 size_t sz = sample_read_value_size(read_format); 1540 struct sample_read_value *v = sample->read.group.values; 1541 1542 sample_read_group__for_each(v, sample->read.group.nr, read_format) { 1543 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ 1544 memcpy(array, v, sz); 1545 array = (void *)array + sz; 1546 } 1547 return array; 1548 } 1549 1550 int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_format, 1551 const struct perf_sample *sample) 1552 { 1553 __u64 *array; 1554 size_t sz; 1555 /* 1556 * used for cross-endian analysis. See git commit 65014ab3 1557 * for why this goofiness is needed. 1558 */ 1559 union u64_swap u; 1560 1561 array = event->sample.array; 1562 1563 if (type & PERF_SAMPLE_IDENTIFIER) { 1564 *array = sample->id; 1565 array++; 1566 } 1567 1568 if (type & PERF_SAMPLE_IP) { 1569 *array = sample->ip; 1570 array++; 1571 } 1572 1573 if (type & PERF_SAMPLE_TID) { 1574 u.val32[0] = sample->pid; 1575 u.val32[1] = sample->tid; 1576 *array = u.val64; 1577 array++; 1578 } 1579 1580 if (type & PERF_SAMPLE_TIME) { 1581 *array = sample->time; 1582 array++; 1583 } 1584 1585 if (type & PERF_SAMPLE_ADDR) { 1586 *array = sample->addr; 1587 array++; 1588 } 1589 1590 if (type & PERF_SAMPLE_ID) { 1591 *array = sample->id; 1592 array++; 1593 } 1594 1595 if (type & PERF_SAMPLE_STREAM_ID) { 1596 *array = sample->stream_id; 1597 array++; 1598 } 1599 1600 if (type & PERF_SAMPLE_CPU) { 1601 u.val32[0] = sample->cpu; 1602 u.val32[1] = 0; 1603 *array = u.val64; 1604 array++; 1605 } 1606 1607 if (type & PERF_SAMPLE_PERIOD) { 1608 *array = sample->period; 1609 array++; 1610 } 1611 1612 if (type & PERF_SAMPLE_READ) { 1613 if (read_format & PERF_FORMAT_GROUP) 1614 *array = sample->read.group.nr; 1615 else 1616 *array = sample->read.one.value; 1617 array++; 1618 1619 if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { 1620 *array = sample->read.time_enabled; 1621 array++; 1622 } 1623 1624 if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) { 1625 *array = sample->read.time_running; 1626 array++; 1627 } 1628 1629 /* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */ 1630 if (read_format & PERF_FORMAT_GROUP) { 1631 array = copy_read_group_values(array, read_format, 1632 sample); 1633 } else { 1634 *array = sample->read.one.id; 1635 array++; 1636 1637 if (read_format & PERF_FORMAT_LOST) { 1638 *array = sample->read.one.lost; 1639 array++; 1640 } 1641 } 1642 } 1643 1644 if (type & PERF_SAMPLE_CALLCHAIN) { 1645 sz = (sample->callchain->nr + 1) * sizeof(u64); 1646 memcpy(array, sample->callchain, sz); 1647 array = (void *)array + sz; 1648 } 1649 1650 if (type & PERF_SAMPLE_RAW) { 1651 u.val32[0] = sample->raw_size; 1652 *array = u.val64; 1653 array = (void *)array + sizeof(u32); 1654 1655 memcpy(array, sample->raw_data, sample->raw_size); 1656 array = (void *)array + sample->raw_size; 1657 } 1658 1659 if (type & PERF_SAMPLE_BRANCH_STACK) { 1660 sz = sample->branch_stack->nr * sizeof(struct branch_entry); 1661 /* nr, hw_idx */ 1662 sz += 2 * sizeof(u64); 1663 memcpy(array, sample->branch_stack, sz); 1664 array = (void *)array + sz; 1665 } 1666 1667 if (type & PERF_SAMPLE_REGS_USER) { 1668 if (sample->user_regs.abi) { 1669 *array++ = sample->user_regs.abi; 1670 sz = hweight64(sample->user_regs.mask) * sizeof(u64); 1671 memcpy(array, sample->user_regs.regs, sz); 1672 array = (void *)array + sz; 1673 } else { 1674 *array++ = 0; 1675 } 1676 } 1677 1678 if (type & PERF_SAMPLE_STACK_USER) { 1679 sz = sample->user_stack.size; 1680 *array++ = sz; 1681 if (sz) { 1682 memcpy(array, sample->user_stack.data, sz); 1683 array = (void *)array + sz; 1684 *array++ = sz; 1685 } 1686 } 1687 1688 if (type & PERF_SAMPLE_WEIGHT_TYPE) { 1689 arch_perf_synthesize_sample_weight(sample, array, type); 1690 array++; 1691 } 1692 1693 if (type & PERF_SAMPLE_DATA_SRC) { 1694 *array = sample->data_src; 1695 array++; 1696 } 1697 1698 if (type & PERF_SAMPLE_TRANSACTION) { 1699 *array = sample->transaction; 1700 array++; 1701 } 1702 1703 if (type & PERF_SAMPLE_REGS_INTR) { 1704 if (sample->intr_regs.abi) { 1705 *array++ = sample->intr_regs.abi; 1706 sz = hweight64(sample->intr_regs.mask) * sizeof(u64); 1707 memcpy(array, sample->intr_regs.regs, sz); 1708 array = (void *)array + sz; 1709 } else { 1710 *array++ = 0; 1711 } 1712 } 1713 1714 if (type & PERF_SAMPLE_PHYS_ADDR) { 1715 *array = sample->phys_addr; 1716 array++; 1717 } 1718 1719 if (type & PERF_SAMPLE_CGROUP) { 1720 *array = sample->cgroup; 1721 array++; 1722 } 1723 1724 if (type & PERF_SAMPLE_DATA_PAGE_SIZE) { 1725 *array = sample->data_page_size; 1726 array++; 1727 } 1728 1729 if (type & PERF_SAMPLE_CODE_PAGE_SIZE) { 1730 *array = sample->code_page_size; 1731 array++; 1732 } 1733 1734 if (type & PERF_SAMPLE_AUX) { 1735 sz = sample->aux_sample.size; 1736 *array++ = sz; 1737 memcpy(array, sample->aux_sample.data, sz); 1738 array = (void *)array + sz; 1739 } 1740 1741 return 0; 1742 } 1743 1744 int perf_event__synthesize_id_sample(__u64 *array, u64 type, const struct perf_sample *sample) 1745 { 1746 __u64 *start = array; 1747 1748 /* 1749 * used for cross-endian analysis. See git commit 65014ab3 1750 * for why this goofiness is needed. 1751 */ 1752 union u64_swap u; 1753 1754 if (type & PERF_SAMPLE_TID) { 1755 u.val32[0] = sample->pid; 1756 u.val32[1] = sample->tid; 1757 *array = u.val64; 1758 array++; 1759 } 1760 1761 if (type & PERF_SAMPLE_TIME) { 1762 *array = sample->time; 1763 array++; 1764 } 1765 1766 if (type & PERF_SAMPLE_ID) { 1767 *array = sample->id; 1768 array++; 1769 } 1770 1771 if (type & PERF_SAMPLE_STREAM_ID) { 1772 *array = sample->stream_id; 1773 array++; 1774 } 1775 1776 if (type & PERF_SAMPLE_CPU) { 1777 u.val32[0] = sample->cpu; 1778 u.val32[1] = 0; 1779 *array = u.val64; 1780 array++; 1781 } 1782 1783 if (type & PERF_SAMPLE_IDENTIFIER) { 1784 *array = sample->id; 1785 array++; 1786 } 1787 1788 return (void *)array - (void *)start; 1789 } 1790 1791 int __perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, 1792 struct evlist *evlist, struct machine *machine, size_t from) 1793 { 1794 union perf_event *ev; 1795 struct evsel *evsel; 1796 size_t nr = 0, i = 0, sz, max_nr, n, pos; 1797 size_t e1_sz = sizeof(struct id_index_entry); 1798 size_t e2_sz = sizeof(struct id_index_entry_2); 1799 size_t etot_sz = e1_sz + e2_sz; 1800 bool e2_needed = false; 1801 int err; 1802 1803 max_nr = (UINT16_MAX - sizeof(struct perf_record_id_index)) / etot_sz; 1804 1805 pos = 0; 1806 evlist__for_each_entry(evlist, evsel) { 1807 if (pos++ < from) 1808 continue; 1809 nr += evsel->core.ids; 1810 } 1811 1812 if (!nr) 1813 return 0; 1814 1815 pr_debug2("Synthesizing id index\n"); 1816 1817 n = nr > max_nr ? max_nr : nr; 1818 sz = sizeof(struct perf_record_id_index) + n * etot_sz; 1819 ev = zalloc(sz); 1820 if (!ev) 1821 return -ENOMEM; 1822 1823 sz = sizeof(struct perf_record_id_index) + n * e1_sz; 1824 1825 ev->id_index.header.type = PERF_RECORD_ID_INDEX; 1826 ev->id_index.nr = n; 1827 1828 pos = 0; 1829 evlist__for_each_entry(evlist, evsel) { 1830 u32 j; 1831 1832 if (pos++ < from) 1833 continue; 1834 for (j = 0; j < evsel->core.ids; j++, i++) { 1835 struct id_index_entry *e; 1836 struct id_index_entry_2 *e2; 1837 struct perf_sample_id *sid; 1838 1839 if (i >= n) { 1840 ev->id_index.header.size = sz + (e2_needed ? n * e2_sz : 0); 1841 err = process(tool, ev, NULL, machine); 1842 if (err) 1843 goto out_err; 1844 nr -= n; 1845 i = 0; 1846 e2_needed = false; 1847 } 1848 1849 e = &ev->id_index.entries[i]; 1850 1851 e->id = evsel->core.id[j]; 1852 1853 sid = evlist__id2sid(evlist, e->id); 1854 if (!sid) { 1855 free(ev); 1856 return -ENOENT; 1857 } 1858 1859 e->idx = sid->idx; 1860 e->cpu = sid->cpu.cpu; 1861 e->tid = sid->tid; 1862 1863 if (sid->machine_pid) 1864 e2_needed = true; 1865 1866 e2 = (void *)ev + sz; 1867 e2[i].machine_pid = sid->machine_pid; 1868 e2[i].vcpu = sid->vcpu.cpu; 1869 } 1870 } 1871 1872 sz = sizeof(struct perf_record_id_index) + nr * e1_sz; 1873 ev->id_index.header.size = sz + (e2_needed ? nr * e2_sz : 0); 1874 ev->id_index.nr = nr; 1875 1876 err = process(tool, ev, NULL, machine); 1877 out_err: 1878 free(ev); 1879 1880 return err; 1881 } 1882 1883 int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_t process, 1884 struct evlist *evlist, struct machine *machine) 1885 { 1886 return __perf_event__synthesize_id_index(tool, process, evlist, machine, 0); 1887 } 1888 1889 int __machine__synthesize_threads(struct machine *machine, struct perf_tool *tool, 1890 struct target *target, struct perf_thread_map *threads, 1891 perf_event__handler_t process, bool needs_mmap, 1892 bool data_mmap, unsigned int nr_threads_synthesize) 1893 { 1894 /* 1895 * When perf runs in non-root PID namespace, and the namespace's proc FS 1896 * is not mounted, nsinfo__is_in_root_namespace() returns false. 1897 * In this case, the proc FS is coming for the parent namespace, thus 1898 * perf tool will wrongly gather process info from its parent PID 1899 * namespace. 1900 * 1901 * To avoid the confusion that the perf tool runs in a child PID 1902 * namespace but it synthesizes thread info from its parent PID 1903 * namespace, returns failure with warning. 1904 */ 1905 if (!nsinfo__is_in_root_namespace()) { 1906 pr_err("Perf runs in non-root PID namespace but it tries to "); 1907 pr_err("gather process info from its parent PID namespace.\n"); 1908 pr_err("Please mount the proc file system properly, e.g. "); 1909 pr_err("add the option '--mount-proc' for unshare command.\n"); 1910 return -EPERM; 1911 } 1912 1913 if (target__has_task(target)) 1914 return perf_event__synthesize_thread_map(tool, threads, process, machine, 1915 needs_mmap, data_mmap); 1916 else if (target__has_cpu(target)) 1917 return perf_event__synthesize_threads(tool, process, machine, 1918 needs_mmap, data_mmap, 1919 nr_threads_synthesize); 1920 /* command specified */ 1921 return 0; 1922 } 1923 1924 int machine__synthesize_threads(struct machine *machine, struct target *target, 1925 struct perf_thread_map *threads, bool needs_mmap, 1926 bool data_mmap, unsigned int nr_threads_synthesize) 1927 { 1928 return __machine__synthesize_threads(machine, NULL, target, threads, 1929 perf_event__process, needs_mmap, 1930 data_mmap, nr_threads_synthesize); 1931 } 1932 1933 static struct perf_record_event_update *event_update_event__new(size_t size, u64 type, u64 id) 1934 { 1935 struct perf_record_event_update *ev; 1936 1937 size += sizeof(*ev); 1938 size = PERF_ALIGN(size, sizeof(u64)); 1939 1940 ev = zalloc(size); 1941 if (ev) { 1942 ev->header.type = PERF_RECORD_EVENT_UPDATE; 1943 ev->header.size = (u16)size; 1944 ev->type = type; 1945 ev->id = id; 1946 } 1947 return ev; 1948 } 1949 1950 int perf_event__synthesize_event_update_unit(struct perf_tool *tool, struct evsel *evsel, 1951 perf_event__handler_t process) 1952 { 1953 size_t size = strlen(evsel->unit); 1954 struct perf_record_event_update *ev; 1955 int err; 1956 1957 ev = event_update_event__new(size + 1, PERF_EVENT_UPDATE__UNIT, evsel->core.id[0]); 1958 if (ev == NULL) 1959 return -ENOMEM; 1960 1961 strlcpy(ev->unit, evsel->unit, size + 1); 1962 err = process(tool, (union perf_event *)ev, NULL, NULL); 1963 free(ev); 1964 return err; 1965 } 1966 1967 int perf_event__synthesize_event_update_scale(struct perf_tool *tool, struct evsel *evsel, 1968 perf_event__handler_t process) 1969 { 1970 struct perf_record_event_update *ev; 1971 struct perf_record_event_update_scale *ev_data; 1972 int err; 1973 1974 ev = event_update_event__new(sizeof(*ev_data), PERF_EVENT_UPDATE__SCALE, evsel->core.id[0]); 1975 if (ev == NULL) 1976 return -ENOMEM; 1977 1978 ev->scale.scale = evsel->scale; 1979 err = process(tool, (union perf_event *)ev, NULL, NULL); 1980 free(ev); 1981 return err; 1982 } 1983 1984 int perf_event__synthesize_event_update_name(struct perf_tool *tool, struct evsel *evsel, 1985 perf_event__handler_t process) 1986 { 1987 struct perf_record_event_update *ev; 1988 size_t len = strlen(evsel->name); 1989 int err; 1990 1991 ev = event_update_event__new(len + 1, PERF_EVENT_UPDATE__NAME, evsel->core.id[0]); 1992 if (ev == NULL) 1993 return -ENOMEM; 1994 1995 strlcpy(ev->name, evsel->name, len + 1); 1996 err = process(tool, (union perf_event *)ev, NULL, NULL); 1997 free(ev); 1998 return err; 1999 } 2000 2001 int perf_event__synthesize_event_update_cpus(struct perf_tool *tool, struct evsel *evsel, 2002 perf_event__handler_t process) 2003 { 2004 struct synthesize_cpu_map_data syn_data = { .map = evsel->core.own_cpus }; 2005 struct perf_record_event_update *ev; 2006 int err; 2007 2008 ev = cpu_map_data__alloc(&syn_data, sizeof(struct perf_event_header) + 2 * sizeof(u64)); 2009 if (!ev) 2010 return -ENOMEM; 2011 2012 syn_data.data = &ev->cpus.cpus; 2013 ev->header.type = PERF_RECORD_EVENT_UPDATE; 2014 ev->header.size = (u16)syn_data.size; 2015 ev->type = PERF_EVENT_UPDATE__CPUS; 2016 ev->id = evsel->core.id[0]; 2017 cpu_map_data__synthesize(&syn_data); 2018 2019 err = process(tool, (union perf_event *)ev, NULL, NULL); 2020 free(ev); 2021 return err; 2022 } 2023 2024 int perf_event__synthesize_attrs(struct perf_tool *tool, struct evlist *evlist, 2025 perf_event__handler_t process) 2026 { 2027 struct evsel *evsel; 2028 int err = 0; 2029 2030 evlist__for_each_entry(evlist, evsel) { 2031 err = perf_event__synthesize_attr(tool, &evsel->core.attr, evsel->core.ids, 2032 evsel->core.id, process); 2033 if (err) { 2034 pr_debug("failed to create perf header attribute\n"); 2035 return err; 2036 } 2037 } 2038 2039 return err; 2040 } 2041 2042 static bool has_unit(struct evsel *evsel) 2043 { 2044 return evsel->unit && *evsel->unit; 2045 } 2046 2047 static bool has_scale(struct evsel *evsel) 2048 { 2049 return evsel->scale != 1; 2050 } 2051 2052 int perf_event__synthesize_extra_attr(struct perf_tool *tool, struct evlist *evsel_list, 2053 perf_event__handler_t process, bool is_pipe) 2054 { 2055 struct evsel *evsel; 2056 int err; 2057 2058 /* 2059 * Synthesize other events stuff not carried within 2060 * attr event - unit, scale, name 2061 */ 2062 evlist__for_each_entry(evsel_list, evsel) { 2063 if (!evsel->supported) 2064 continue; 2065 2066 /* 2067 * Synthesize unit and scale only if it's defined. 2068 */ 2069 if (has_unit(evsel)) { 2070 err = perf_event__synthesize_event_update_unit(tool, evsel, process); 2071 if (err < 0) { 2072 pr_err("Couldn't synthesize evsel unit.\n"); 2073 return err; 2074 } 2075 } 2076 2077 if (has_scale(evsel)) { 2078 err = perf_event__synthesize_event_update_scale(tool, evsel, process); 2079 if (err < 0) { 2080 pr_err("Couldn't synthesize evsel evsel.\n"); 2081 return err; 2082 } 2083 } 2084 2085 if (evsel->core.own_cpus) { 2086 err = perf_event__synthesize_event_update_cpus(tool, evsel, process); 2087 if (err < 0) { 2088 pr_err("Couldn't synthesize evsel cpus.\n"); 2089 return err; 2090 } 2091 } 2092 2093 /* 2094 * Name is needed only for pipe output, 2095 * perf.data carries event names. 2096 */ 2097 if (is_pipe) { 2098 err = perf_event__synthesize_event_update_name(tool, evsel, process); 2099 if (err < 0) { 2100 pr_err("Couldn't synthesize evsel name.\n"); 2101 return err; 2102 } 2103 } 2104 } 2105 return 0; 2106 } 2107 2108 int perf_event__synthesize_attr(struct perf_tool *tool, struct perf_event_attr *attr, 2109 u32 ids, u64 *id, perf_event__handler_t process) 2110 { 2111 union perf_event *ev; 2112 size_t size; 2113 int err; 2114 2115 size = sizeof(struct perf_event_attr); 2116 size = PERF_ALIGN(size, sizeof(u64)); 2117 size += sizeof(struct perf_event_header); 2118 size += ids * sizeof(u64); 2119 2120 ev = zalloc(size); 2121 2122 if (ev == NULL) 2123 return -ENOMEM; 2124 2125 ev->attr.attr = *attr; 2126 memcpy(ev->attr.id, id, ids * sizeof(u64)); 2127 2128 ev->attr.header.type = PERF_RECORD_HEADER_ATTR; 2129 ev->attr.header.size = (u16)size; 2130 2131 if (ev->attr.header.size == size) 2132 err = process(tool, ev, NULL, NULL); 2133 else 2134 err = -E2BIG; 2135 2136 free(ev); 2137 2138 return err; 2139 } 2140 2141 int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd, struct evlist *evlist, 2142 perf_event__handler_t process) 2143 { 2144 union perf_event ev; 2145 struct tracing_data *tdata; 2146 ssize_t size = 0, aligned_size = 0, padding; 2147 struct feat_fd ff; 2148 2149 /* 2150 * We are going to store the size of the data followed 2151 * by the data contents. Since the fd descriptor is a pipe, 2152 * we cannot seek back to store the size of the data once 2153 * we know it. Instead we: 2154 * 2155 * - write the tracing data to the temp file 2156 * - get/write the data size to pipe 2157 * - write the tracing data from the temp file 2158 * to the pipe 2159 */ 2160 tdata = tracing_data_get(&evlist->core.entries, fd, true); 2161 if (!tdata) 2162 return -1; 2163 2164 memset(&ev, 0, sizeof(ev)); 2165 2166 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; 2167 size = tdata->size; 2168 aligned_size = PERF_ALIGN(size, sizeof(u64)); 2169 padding = aligned_size - size; 2170 ev.tracing_data.header.size = sizeof(ev.tracing_data); 2171 ev.tracing_data.size = aligned_size; 2172 2173 process(tool, &ev, NULL, NULL); 2174 2175 /* 2176 * The put function will copy all the tracing data 2177 * stored in temp file to the pipe. 2178 */ 2179 tracing_data_put(tdata); 2180 2181 ff = (struct feat_fd){ .fd = fd }; 2182 if (write_padded(&ff, NULL, 0, padding)) 2183 return -1; 2184 2185 return aligned_size; 2186 } 2187 2188 int perf_event__synthesize_build_id(struct perf_tool *tool, struct dso *pos, u16 misc, 2189 perf_event__handler_t process, struct machine *machine) 2190 { 2191 union perf_event ev; 2192 size_t len; 2193 2194 if (!pos->hit) 2195 return 0; 2196 2197 memset(&ev, 0, sizeof(ev)); 2198 2199 len = pos->long_name_len + 1; 2200 len = PERF_ALIGN(len, NAME_ALIGN); 2201 memcpy(&ev.build_id.build_id, pos->bid.data, sizeof(pos->bid.data)); 2202 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; 2203 ev.build_id.header.misc = misc; 2204 ev.build_id.pid = machine->pid; 2205 ev.build_id.header.size = sizeof(ev.build_id) + len; 2206 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); 2207 2208 return process(tool, &ev, NULL, machine); 2209 } 2210 2211 int perf_event__synthesize_stat_events(struct perf_stat_config *config, struct perf_tool *tool, 2212 struct evlist *evlist, perf_event__handler_t process, bool attrs) 2213 { 2214 int err; 2215 2216 if (attrs) { 2217 err = perf_event__synthesize_attrs(tool, evlist, process); 2218 if (err < 0) { 2219 pr_err("Couldn't synthesize attrs.\n"); 2220 return err; 2221 } 2222 } 2223 2224 err = perf_event__synthesize_extra_attr(tool, evlist, process, attrs); 2225 err = perf_event__synthesize_thread_map2(tool, evlist->core.threads, process, NULL); 2226 if (err < 0) { 2227 pr_err("Couldn't synthesize thread map.\n"); 2228 return err; 2229 } 2230 2231 err = perf_event__synthesize_cpu_map(tool, evlist->core.user_requested_cpus, process, NULL); 2232 if (err < 0) { 2233 pr_err("Couldn't synthesize thread map.\n"); 2234 return err; 2235 } 2236 2237 err = perf_event__synthesize_stat_config(tool, config, process, NULL); 2238 if (err < 0) { 2239 pr_err("Couldn't synthesize config.\n"); 2240 return err; 2241 } 2242 2243 return 0; 2244 } 2245 2246 extern const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE]; 2247 2248 int perf_event__synthesize_features(struct perf_tool *tool, struct perf_session *session, 2249 struct evlist *evlist, perf_event__handler_t process) 2250 { 2251 struct perf_header *header = &session->header; 2252 struct perf_record_header_feature *fe; 2253 struct feat_fd ff; 2254 size_t sz, sz_hdr; 2255 int feat, ret; 2256 2257 sz_hdr = sizeof(fe->header); 2258 sz = sizeof(union perf_event); 2259 /* get a nice alignment */ 2260 sz = PERF_ALIGN(sz, page_size); 2261 2262 memset(&ff, 0, sizeof(ff)); 2263 2264 ff.buf = malloc(sz); 2265 if (!ff.buf) 2266 return -ENOMEM; 2267 2268 ff.size = sz - sz_hdr; 2269 ff.ph = &session->header; 2270 2271 for_each_set_bit(feat, header->adds_features, HEADER_FEAT_BITS) { 2272 if (!feat_ops[feat].synthesize) { 2273 pr_debug("No record header feature for header :%d\n", feat); 2274 continue; 2275 } 2276 2277 ff.offset = sizeof(*fe); 2278 2279 ret = feat_ops[feat].write(&ff, evlist); 2280 if (ret || ff.offset <= (ssize_t)sizeof(*fe)) { 2281 pr_debug("Error writing feature\n"); 2282 continue; 2283 } 2284 /* ff.buf may have changed due to realloc in do_write() */ 2285 fe = ff.buf; 2286 memset(fe, 0, sizeof(*fe)); 2287 2288 fe->feat_id = feat; 2289 fe->header.type = PERF_RECORD_HEADER_FEATURE; 2290 fe->header.size = ff.offset; 2291 2292 ret = process(tool, ff.buf, NULL, NULL); 2293 if (ret) { 2294 free(ff.buf); 2295 return ret; 2296 } 2297 } 2298 2299 /* Send HEADER_LAST_FEATURE mark. */ 2300 fe = ff.buf; 2301 fe->feat_id = HEADER_LAST_FEATURE; 2302 fe->header.type = PERF_RECORD_HEADER_FEATURE; 2303 fe->header.size = sizeof(*fe); 2304 2305 ret = process(tool, ff.buf, NULL, NULL); 2306 2307 free(ff.buf); 2308 return ret; 2309 } 2310 2311 int perf_event__synthesize_for_pipe(struct perf_tool *tool, 2312 struct perf_session *session, 2313 struct perf_data *data, 2314 perf_event__handler_t process) 2315 { 2316 int err; 2317 int ret = 0; 2318 struct evlist *evlist = session->evlist; 2319 2320 /* 2321 * We need to synthesize events first, because some 2322 * features works on top of them (on report side). 2323 */ 2324 err = perf_event__synthesize_attrs(tool, evlist, process); 2325 if (err < 0) { 2326 pr_err("Couldn't synthesize attrs.\n"); 2327 return err; 2328 } 2329 ret += err; 2330 2331 err = perf_event__synthesize_features(tool, session, evlist, process); 2332 if (err < 0) { 2333 pr_err("Couldn't synthesize features.\n"); 2334 return err; 2335 } 2336 ret += err; 2337 2338 if (have_tracepoints(&evlist->core.entries)) { 2339 int fd = perf_data__fd(data); 2340 2341 /* 2342 * FIXME err <= 0 here actually means that 2343 * there were no tracepoints so its not really 2344 * an error, just that we don't need to 2345 * synthesize anything. We really have to 2346 * return this more properly and also 2347 * propagate errors that now are calling die() 2348 */ 2349 err = perf_event__synthesize_tracing_data(tool, fd, evlist, 2350 process); 2351 if (err <= 0) { 2352 pr_err("Couldn't record tracing data.\n"); 2353 return err; 2354 } 2355 ret += err; 2356 } 2357 2358 return ret; 2359 } 2360 2361 int parse_synth_opt(char *synth) 2362 { 2363 char *p, *q; 2364 int ret = 0; 2365 2366 if (synth == NULL) 2367 return -1; 2368 2369 for (q = synth; (p = strsep(&q, ",")); p = q) { 2370 if (!strcasecmp(p, "no") || !strcasecmp(p, "none")) 2371 return 0; 2372 2373 if (!strcasecmp(p, "all")) 2374 return PERF_SYNTH_ALL; 2375 2376 if (!strcasecmp(p, "task")) 2377 ret |= PERF_SYNTH_TASK; 2378 else if (!strcasecmp(p, "mmap")) 2379 ret |= PERF_SYNTH_TASK | PERF_SYNTH_MMAP; 2380 else if (!strcasecmp(p, "cgroup")) 2381 ret |= PERF_SYNTH_CGROUP; 2382 else 2383 return -1; 2384 } 2385 2386 return ret; 2387 } 2388