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