diff options
Diffstat (limited to 'tools/perf/util/util.c')
-rw-r--r-- | tools/perf/util/util.c | 136 |
1 files changed, 130 insertions, 6 deletions
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 28a0a89c1f73..42ad667bb317 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -1,11 +1,17 @@ | |||
1 | #include "../perf.h" | 1 | #include "../perf.h" |
2 | #include "util.h" | 2 | #include "util.h" |
3 | #include "fs.h" | ||
3 | #include <sys/mman.h> | 4 | #include <sys/mman.h> |
4 | #ifdef HAVE_BACKTRACE_SUPPORT | 5 | #ifdef HAVE_BACKTRACE_SUPPORT |
5 | #include <execinfo.h> | 6 | #include <execinfo.h> |
6 | #endif | 7 | #endif |
7 | #include <stdio.h> | 8 | #include <stdio.h> |
8 | #include <stdlib.h> | 9 | #include <stdlib.h> |
10 | #include <string.h> | ||
11 | #include <errno.h> | ||
12 | #include <limits.h> | ||
13 | #include <byteswap.h> | ||
14 | #include <linux/kernel.h> | ||
9 | 15 | ||
10 | /* | 16 | /* |
11 | * XXX We need to find a better place for these things... | 17 | * XXX We need to find a better place for these things... |
@@ -151,21 +157,40 @@ unsigned long convert_unit(unsigned long value, char *unit) | |||
151 | return value; | 157 | return value; |
152 | } | 158 | } |
153 | 159 | ||
154 | int readn(int fd, void *buf, size_t n) | 160 | static ssize_t ion(bool is_read, int fd, void *buf, size_t n) |
155 | { | 161 | { |
156 | void *buf_start = buf; | 162 | void *buf_start = buf; |
163 | size_t left = n; | ||
157 | 164 | ||
158 | while (n) { | 165 | while (left) { |
159 | int ret = read(fd, buf, n); | 166 | ssize_t ret = is_read ? read(fd, buf, left) : |
167 | write(fd, buf, left); | ||
160 | 168 | ||
161 | if (ret <= 0) | 169 | if (ret <= 0) |
162 | return ret; | 170 | return ret; |
163 | 171 | ||
164 | n -= ret; | 172 | left -= ret; |
165 | buf += ret; | 173 | buf += ret; |
166 | } | 174 | } |
167 | 175 | ||
168 | return buf - buf_start; | 176 | BUG_ON((size_t)(buf - buf_start) != n); |
177 | return n; | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Read exactly 'n' bytes or return an error. | ||
182 | */ | ||
183 | ssize_t readn(int fd, void *buf, size_t n) | ||
184 | { | ||
185 | return ion(true, fd, buf, n); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Write exactly 'n' bytes or return an error. | ||
190 | */ | ||
191 | ssize_t writen(int fd, void *buf, size_t n) | ||
192 | { | ||
193 | return ion(false, fd, buf, n); | ||
169 | } | 194 | } |
170 | 195 | ||
171 | size_t hex_width(u64 v) | 196 | size_t hex_width(u64 v) |
@@ -413,3 +438,102 @@ int filename__read_int(const char *filename, int *value) | |||
413 | close(fd); | 438 | close(fd); |
414 | return err; | 439 | return err; |
415 | } | 440 | } |
441 | |||
442 | int filename__read_str(const char *filename, char **buf, size_t *sizep) | ||
443 | { | ||
444 | size_t size = 0, alloc_size = 0; | ||
445 | void *bf = NULL, *nbf; | ||
446 | int fd, n, err = 0; | ||
447 | |||
448 | fd = open(filename, O_RDONLY); | ||
449 | if (fd < 0) | ||
450 | return -errno; | ||
451 | |||
452 | do { | ||
453 | if (size == alloc_size) { | ||
454 | alloc_size += BUFSIZ; | ||
455 | nbf = realloc(bf, alloc_size); | ||
456 | if (!nbf) { | ||
457 | err = -ENOMEM; | ||
458 | break; | ||
459 | } | ||
460 | |||
461 | bf = nbf; | ||
462 | } | ||
463 | |||
464 | n = read(fd, bf + size, alloc_size - size); | ||
465 | if (n < 0) { | ||
466 | if (size) { | ||
467 | pr_warning("read failed %d: %s\n", | ||
468 | errno, strerror(errno)); | ||
469 | err = 0; | ||
470 | } else | ||
471 | err = -errno; | ||
472 | |||
473 | break; | ||
474 | } | ||
475 | |||
476 | size += n; | ||
477 | } while (n > 0); | ||
478 | |||
479 | if (!err) { | ||
480 | *sizep = size; | ||
481 | *buf = bf; | ||
482 | } else | ||
483 | free(bf); | ||
484 | |||
485 | close(fd); | ||
486 | return err; | ||
487 | } | ||
488 | |||
489 | const char *get_filename_for_perf_kvm(void) | ||
490 | { | ||
491 | const char *filename; | ||
492 | |||
493 | if (perf_host && !perf_guest) | ||
494 | filename = strdup("perf.data.host"); | ||
495 | else if (!perf_host && perf_guest) | ||
496 | filename = strdup("perf.data.guest"); | ||
497 | else | ||
498 | filename = strdup("perf.data.kvm"); | ||
499 | |||
500 | return filename; | ||
501 | } | ||
502 | |||
503 | int perf_event_paranoid(void) | ||
504 | { | ||
505 | char path[PATH_MAX]; | ||
506 | const char *procfs = procfs__mountpoint(); | ||
507 | int value; | ||
508 | |||
509 | if (!procfs) | ||
510 | return INT_MAX; | ||
511 | |||
512 | scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs); | ||
513 | |||
514 | if (filename__read_int(path, &value)) | ||
515 | return INT_MAX; | ||
516 | |||
517 | return value; | ||
518 | } | ||
519 | |||
520 | void mem_bswap_32(void *src, int byte_size) | ||
521 | { | ||
522 | u32 *m = src; | ||
523 | while (byte_size > 0) { | ||
524 | *m = bswap_32(*m); | ||
525 | byte_size -= sizeof(u32); | ||
526 | ++m; | ||
527 | } | ||
528 | } | ||
529 | |||
530 | void mem_bswap_64(void *src, int byte_size) | ||
531 | { | ||
532 | u64 *m = src; | ||
533 | |||
534 | while (byte_size > 0) { | ||
535 | *m = bswap_64(*m); | ||
536 | byte_size -= sizeof(u64); | ||
537 | ++m; | ||
538 | } | ||
539 | } | ||