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