1 #include "../perf.h" 2 #include "util.h" 3 #include "debug.h" 4 #include <api/fs/fs.h> 5 #include <sys/mman.h> 6 #ifdef HAVE_BACKTRACE_SUPPORT 7 #include <execinfo.h> 8 #endif 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <errno.h> 13 #include <limits.h> 14 #include <byteswap.h> 15 #include <linux/kernel.h> 16 #include <unistd.h> 17 #include "callchain.h" 18 19 struct callchain_param callchain_param = { 20 .mode = CHAIN_GRAPH_REL, 21 .min_percent = 0.5, 22 .order = ORDER_CALLEE, 23 .key = CCKEY_FUNCTION 24 }; 25 26 /* 27 * XXX We need to find a better place for these things... 28 */ 29 unsigned int page_size; 30 int cacheline_size; 31 32 bool test_attr__enabled; 33 34 bool perf_host = true; 35 bool perf_guest = false; 36 37 char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events"; 38 39 void event_attr_init(struct perf_event_attr *attr) 40 { 41 if (!perf_host) 42 attr->exclude_host = 1; 43 if (!perf_guest) 44 attr->exclude_guest = 1; 45 /* to capture ABI version */ 46 attr->size = sizeof(*attr); 47 } 48 49 int mkdir_p(char *path, mode_t mode) 50 { 51 struct stat st; 52 int err; 53 char *d = path; 54 55 if (*d != '/') 56 return -1; 57 58 if (stat(path, &st) == 0) 59 return 0; 60 61 while (*++d == '/'); 62 63 while ((d = strchr(d, '/'))) { 64 *d = '\0'; 65 err = stat(path, &st) && mkdir(path, mode); 66 *d++ = '/'; 67 if (err) 68 return -1; 69 while (*d == '/') 70 ++d; 71 } 72 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 73 } 74 75 int rm_rf(char *path) 76 { 77 DIR *dir; 78 int ret = 0; 79 struct dirent *d; 80 char namebuf[PATH_MAX]; 81 82 dir = opendir(path); 83 if (dir == NULL) 84 return 0; 85 86 while ((d = readdir(dir)) != NULL && !ret) { 87 struct stat statbuf; 88 89 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) 90 continue; 91 92 scnprintf(namebuf, sizeof(namebuf), "%s/%s", 93 path, d->d_name); 94 95 ret = stat(namebuf, &statbuf); 96 if (ret < 0) { 97 pr_debug("stat failed: %s\n", namebuf); 98 break; 99 } 100 101 if (S_ISREG(statbuf.st_mode)) 102 ret = unlink(namebuf); 103 else if (S_ISDIR(statbuf.st_mode)) 104 ret = rm_rf(namebuf); 105 else { 106 pr_debug("unknown file: %s\n", namebuf); 107 ret = -1; 108 } 109 } 110 closedir(dir); 111 112 if (ret < 0) 113 return ret; 114 115 return rmdir(path); 116 } 117 118 static int slow_copyfile(const char *from, const char *to, mode_t mode) 119 { 120 int err = -1; 121 char *line = NULL; 122 size_t n; 123 FILE *from_fp = fopen(from, "r"), *to_fp; 124 mode_t old_umask; 125 126 if (from_fp == NULL) 127 goto out; 128 129 old_umask = umask(mode ^ 0777); 130 to_fp = fopen(to, "w"); 131 umask(old_umask); 132 if (to_fp == NULL) 133 goto out_fclose_from; 134 135 while (getline(&line, &n, from_fp) > 0) 136 if (fputs(line, to_fp) == EOF) 137 goto out_fclose_to; 138 err = 0; 139 out_fclose_to: 140 fclose(to_fp); 141 free(line); 142 out_fclose_from: 143 fclose(from_fp); 144 out: 145 return err; 146 } 147 148 int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) 149 { 150 void *ptr; 151 loff_t pgoff; 152 153 pgoff = off_in & ~(page_size - 1); 154 off_in -= pgoff; 155 156 ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); 157 if (ptr == MAP_FAILED) 158 return -1; 159 160 while (size) { 161 ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); 162 if (ret < 0 && errno == EINTR) 163 continue; 164 if (ret <= 0) 165 break; 166 167 size -= ret; 168 off_in += ret; 169 off_out -= ret; 170 } 171 munmap(ptr, off_in + size); 172 173 return size ? -1 : 0; 174 } 175 176 int copyfile_mode(const char *from, const char *to, mode_t mode) 177 { 178 int fromfd, tofd; 179 struct stat st; 180 int err = -1; 181 182 if (stat(from, &st)) 183 goto out; 184 185 if (st.st_size == 0) /* /proc? do it slowly... */ 186 return slow_copyfile(from, to, mode); 187 188 fromfd = open(from, O_RDONLY); 189 if (fromfd < 0) 190 goto out; 191 192 tofd = creat(to, mode); 193 if (tofd < 0) 194 goto out_close_from; 195 196 err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); 197 198 close(tofd); 199 if (err) 200 unlink(to); 201 out_close_from: 202 close(fromfd); 203 out: 204 return err; 205 } 206 207 int copyfile(const char *from, const char *to) 208 { 209 return copyfile_mode(from, to, 0755); 210 } 211 212 unsigned long convert_unit(unsigned long value, char *unit) 213 { 214 *unit = ' '; 215 216 if (value > 1000) { 217 value /= 1000; 218 *unit = 'K'; 219 } 220 221 if (value > 1000) { 222 value /= 1000; 223 *unit = 'M'; 224 } 225 226 if (value > 1000) { 227 value /= 1000; 228 *unit = 'G'; 229 } 230 231 return value; 232 } 233 234 static ssize_t ion(bool is_read, int fd, void *buf, size_t n) 235 { 236 void *buf_start = buf; 237 size_t left = n; 238 239 while (left) { 240 ssize_t ret = is_read ? read(fd, buf, left) : 241 write(fd, buf, left); 242 243 if (ret < 0 && errno == EINTR) 244 continue; 245 if (ret <= 0) 246 return ret; 247 248 left -= ret; 249 buf += ret; 250 } 251 252 BUG_ON((size_t)(buf - buf_start) != n); 253 return n; 254 } 255 256 /* 257 * Read exactly 'n' bytes or return an error. 258 */ 259 ssize_t readn(int fd, void *buf, size_t n) 260 { 261 return ion(true, fd, buf, n); 262 } 263 264 /* 265 * Write exactly 'n' bytes or return an error. 266 */ 267 ssize_t writen(int fd, void *buf, size_t n) 268 { 269 return ion(false, fd, buf, n); 270 } 271 272 size_t hex_width(u64 v) 273 { 274 size_t n = 1; 275 276 while ((v >>= 4)) 277 ++n; 278 279 return n; 280 } 281 282 static int hex(char ch) 283 { 284 if ((ch >= '0') && (ch <= '9')) 285 return ch - '0'; 286 if ((ch >= 'a') && (ch <= 'f')) 287 return ch - 'a' + 10; 288 if ((ch >= 'A') && (ch <= 'F')) 289 return ch - 'A' + 10; 290 return -1; 291 } 292 293 /* 294 * While we find nice hex chars, build a long_val. 295 * Return number of chars processed. 296 */ 297 int hex2u64(const char *ptr, u64 *long_val) 298 { 299 const char *p = ptr; 300 *long_val = 0; 301 302 while (*p) { 303 const int hex_val = hex(*p); 304 305 if (hex_val < 0) 306 break; 307 308 *long_val = (*long_val << 4) | hex_val; 309 p++; 310 } 311 312 return p - ptr; 313 } 314 315 /* Obtain a backtrace and print it to stdout. */ 316 #ifdef HAVE_BACKTRACE_SUPPORT 317 void dump_stack(void) 318 { 319 void *array[16]; 320 size_t size = backtrace(array, ARRAY_SIZE(array)); 321 char **strings = backtrace_symbols(array, size); 322 size_t i; 323 324 printf("Obtained %zd stack frames.\n", size); 325 326 for (i = 0; i < size; i++) 327 printf("%s\n", strings[i]); 328 329 free(strings); 330 } 331 #else 332 void dump_stack(void) {} 333 #endif 334 335 void sighandler_dump_stack(int sig) 336 { 337 psignal(sig, "perf"); 338 dump_stack(); 339 exit(sig); 340 } 341 342 void get_term_dimensions(struct winsize *ws) 343 { 344 char *s = getenv("LINES"); 345 346 if (s != NULL) { 347 ws->ws_row = atoi(s); 348 s = getenv("COLUMNS"); 349 if (s != NULL) { 350 ws->ws_col = atoi(s); 351 if (ws->ws_row && ws->ws_col) 352 return; 353 } 354 } 355 #ifdef TIOCGWINSZ 356 if (ioctl(1, TIOCGWINSZ, ws) == 0 && 357 ws->ws_row && ws->ws_col) 358 return; 359 #endif 360 ws->ws_row = 25; 361 ws->ws_col = 80; 362 } 363 364 void set_term_quiet_input(struct termios *old) 365 { 366 struct termios tc; 367 368 tcgetattr(0, old); 369 tc = *old; 370 tc.c_lflag &= ~(ICANON | ECHO); 371 tc.c_cc[VMIN] = 0; 372 tc.c_cc[VTIME] = 0; 373 tcsetattr(0, TCSANOW, &tc); 374 } 375 376 static void set_tracing_events_path(const char *tracing, const char *mountpoint) 377 { 378 snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s", 379 mountpoint, tracing, "events"); 380 } 381 382 static const char *__perf_tracefs_mount(const char *mountpoint) 383 { 384 const char *mnt; 385 386 mnt = tracefs_mount(mountpoint); 387 if (!mnt) 388 return NULL; 389 390 set_tracing_events_path("", mnt); 391 392 return mnt; 393 } 394 395 static const char *__perf_debugfs_mount(const char *mountpoint) 396 { 397 const char *mnt; 398 399 mnt = debugfs_mount(mountpoint); 400 if (!mnt) 401 return NULL; 402 403 set_tracing_events_path("tracing/", mnt); 404 405 return mnt; 406 } 407 408 const char *perf_debugfs_mount(const char *mountpoint) 409 { 410 const char *mnt; 411 412 mnt = __perf_tracefs_mount(mountpoint); 413 if (mnt) 414 return mnt; 415 416 mnt = __perf_debugfs_mount(mountpoint); 417 418 return mnt; 419 } 420 421 void perf_debugfs_set_path(const char *mntpt) 422 { 423 snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt); 424 set_tracing_events_path("tracing/", mntpt); 425 } 426 427 static const char *find_tracefs(void) 428 { 429 const char *path = __perf_tracefs_mount(NULL); 430 431 return path; 432 } 433 434 static const char *find_debugfs(void) 435 { 436 const char *path = __perf_debugfs_mount(NULL); 437 438 if (!path) 439 fprintf(stderr, "Your kernel does not support the debugfs filesystem"); 440 441 return path; 442 } 443 444 /* 445 * Finds the path to the debugfs/tracing 446 * Allocates the string and stores it. 447 */ 448 const char *find_tracing_dir(void) 449 { 450 const char *tracing_dir = ""; 451 static char *tracing; 452 static int tracing_found; 453 const char *debugfs; 454 455 if (tracing_found) 456 return tracing; 457 458 debugfs = find_tracefs(); 459 if (!debugfs) { 460 tracing_dir = "/tracing"; 461 debugfs = find_debugfs(); 462 if (!debugfs) 463 return NULL; 464 } 465 466 if (asprintf(&tracing, "%s%s", debugfs, tracing_dir) < 0) 467 return NULL; 468 469 tracing_found = 1; 470 return tracing; 471 } 472 473 char *get_tracing_file(const char *name) 474 { 475 const char *tracing; 476 char *file; 477 478 tracing = find_tracing_dir(); 479 if (!tracing) 480 return NULL; 481 482 if (asprintf(&file, "%s/%s", tracing, name) < 0) 483 return NULL; 484 485 return file; 486 } 487 488 void put_tracing_file(char *file) 489 { 490 free(file); 491 } 492 493 int parse_nsec_time(const char *str, u64 *ptime) 494 { 495 u64 time_sec, time_nsec; 496 char *end; 497 498 time_sec = strtoul(str, &end, 10); 499 if (*end != '.' && *end != '\0') 500 return -1; 501 502 if (*end == '.') { 503 int i; 504 char nsec_buf[10]; 505 506 if (strlen(++end) > 9) 507 return -1; 508 509 strncpy(nsec_buf, end, 9); 510 nsec_buf[9] = '\0'; 511 512 /* make it nsec precision */ 513 for (i = strlen(nsec_buf); i < 9; i++) 514 nsec_buf[i] = '0'; 515 516 time_nsec = strtoul(nsec_buf, &end, 10); 517 if (*end != '\0') 518 return -1; 519 } else 520 time_nsec = 0; 521 522 *ptime = time_sec * NSEC_PER_SEC + time_nsec; 523 return 0; 524 } 525 526 unsigned long parse_tag_value(const char *str, struct parse_tag *tags) 527 { 528 struct parse_tag *i = tags; 529 530 while (i->tag) { 531 char *s; 532 533 s = strchr(str, i->tag); 534 if (s) { 535 unsigned long int value; 536 char *endptr; 537 538 value = strtoul(str, &endptr, 10); 539 if (s != endptr) 540 break; 541 542 if (value > ULONG_MAX / i->mult) 543 break; 544 value *= i->mult; 545 return value; 546 } 547 i++; 548 } 549 550 return (unsigned long) -1; 551 } 552 553 int filename__read_str(const char *filename, char **buf, size_t *sizep) 554 { 555 size_t size = 0, alloc_size = 0; 556 void *bf = NULL, *nbf; 557 int fd, n, err = 0; 558 char sbuf[STRERR_BUFSIZE]; 559 560 fd = open(filename, O_RDONLY); 561 if (fd < 0) 562 return -errno; 563 564 do { 565 if (size == alloc_size) { 566 alloc_size += BUFSIZ; 567 nbf = realloc(bf, alloc_size); 568 if (!nbf) { 569 err = -ENOMEM; 570 break; 571 } 572 573 bf = nbf; 574 } 575 576 n = read(fd, bf + size, alloc_size - size); 577 if (n < 0) { 578 if (size) { 579 pr_warning("read failed %d: %s\n", errno, 580 strerror_r(errno, sbuf, sizeof(sbuf))); 581 err = 0; 582 } else 583 err = -errno; 584 585 break; 586 } 587 588 size += n; 589 } while (n > 0); 590 591 if (!err) { 592 *sizep = size; 593 *buf = bf; 594 } else 595 free(bf); 596 597 close(fd); 598 return err; 599 } 600 601 const char *get_filename_for_perf_kvm(void) 602 { 603 const char *filename; 604 605 if (perf_host && !perf_guest) 606 filename = strdup("perf.data.host"); 607 else if (!perf_host && perf_guest) 608 filename = strdup("perf.data.guest"); 609 else 610 filename = strdup("perf.data.kvm"); 611 612 return filename; 613 } 614 615 int perf_event_paranoid(void) 616 { 617 int value; 618 619 if (sysctl__read_int("kernel/perf_event_paranoid", &value)) 620 return INT_MAX; 621 622 return value; 623 } 624 625 void mem_bswap_32(void *src, int byte_size) 626 { 627 u32 *m = src; 628 while (byte_size > 0) { 629 *m = bswap_32(*m); 630 byte_size -= sizeof(u32); 631 ++m; 632 } 633 } 634 635 void mem_bswap_64(void *src, int byte_size) 636 { 637 u64 *m = src; 638 639 while (byte_size > 0) { 640 *m = bswap_64(*m); 641 byte_size -= sizeof(u64); 642 ++m; 643 } 644 } 645 646 bool find_process(const char *name) 647 { 648 size_t len = strlen(name); 649 DIR *dir; 650 struct dirent *d; 651 int ret = -1; 652 653 dir = opendir(procfs__mountpoint()); 654 if (!dir) 655 return -1; 656 657 /* Walk through the directory. */ 658 while (ret && (d = readdir(dir)) != NULL) { 659 char path[PATH_MAX]; 660 char *data; 661 size_t size; 662 663 if ((d->d_type != DT_DIR) || 664 !strcmp(".", d->d_name) || 665 !strcmp("..", d->d_name)) 666 continue; 667 668 scnprintf(path, sizeof(path), "%s/%s/comm", 669 procfs__mountpoint(), d->d_name); 670 671 if (filename__read_str(path, &data, &size)) 672 continue; 673 674 ret = strncmp(name, data, len); 675 free(data); 676 } 677 678 closedir(dir); 679 return ret ? false : true; 680 } 681