diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-01 20:23:17 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-01 20:23:17 -0700 |
commit | 7c8c03bfc7b9f5211d8a69eab7fee99c9fb4f449 (patch) | |
tree | a5cee67325e50e893bf0cc0a0d060983a0df6653 /tools/perf/util/util.c | |
parent | 6dc2cce9321198172cd96f955a5fc798a4cc35a6 (diff) | |
parent | fd7647979a3948dae4fc6f25dbbdf9ba269bed78 (diff) |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar:
"The main changes in this cycle were:
Kernel side changes:
- Kprobes and uprobes changes:
- Make their trampolines read-only while they are used
- Make UPROBES_EVENTS default-y which is the distro practice
- Apply misc fixes and robustization to probe point insertion.
- add support for AMD IOMMU events
- extend hw events on Intel Goldmont CPUs
- ... plus misc fixes and updates.
Tooling side changes:
- support s390 jump instructions in perf annotate (Christian
Borntraeger)
- vendor hardware events updates (Andi Kleen)
- add argument support for SDT events in powerpc (Ravi Bangoria)
- beautify the statx syscall arguments in 'perf trace' (Arnaldo
Carvalho de Melo)
- handle inline functions in callchains (Jin Yao)
- enable sorting by srcline as key (Milian Wolff)
- add 'brstackinsn' field in 'perf script' to reuse the x86
instruction decoder used in the Intel PT code to study hot paths to
samples (Andi Kleen)
- add PERF_RECORD_NAMESPACES so that the kernel can record
information required to associate samples to namespaces, helping in
container problem characterization. (Hari Bathini)
- allow sorting by symbol_size in 'perf report' and 'perf top'
(Charles Baylis)
- in perf stat, make system wide (-a) the default option if no target
was specified and one of following conditions is met:
- no workload specified (current behaviour)
- a workload is specified but all requested events are system wide
ones, like uncore ones. (Jiri Olsa)
- ... plus lots of other updates, enhancements, cleanups and fixes"
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (235 commits)
perf tools: Fix the code to strip command name
tools arch x86: Sync cpufeatures.h
tools arch: Sync arch/x86/lib/memcpy_64.S with the kernel
tools: Update asm-generic/mman-common.h copy from the kernel
perf tools: Use just forward declarations for struct thread where possible
perf tools: Add the right header to obtain PERF_ALIGN()
perf tools: Remove poll.h and wait.h from util.h
perf tools: Remove string.h, unistd.h and sys/stat.h from util.h
perf tools: Remove stale prototypes from builtin.h
perf tools: Remove string.h from util.h
perf tools: Remove sys/ioctl.h from util.h
perf tools: Remove a few more needless includes from util.h
perf tools: Include sys/param.h where needed
perf callchain: Move callchain specific routines from util.[ch]
perf tools: Add compress.h for the *_decompress_to_file() headers
perf mem: Fix display of data source snoop indication
perf debug: Move dump_stack() and sighandler_dump_stack() to debug.h
perf kvm: Make function only used by 'perf kvm' static
perf tools: Move timestamp routines from util.h to time-utils.h
perf tools: Move units conversion/formatting routines to separate object
...
Diffstat (limited to 'tools/perf/util/util.c')
-rw-r--r-- | tools/perf/util/util.c | 278 |
1 files changed, 6 insertions, 272 deletions
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index d8b45cea54d0..6450c75a6f5b 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -3,10 +3,11 @@ #include "debug.h" #include <api/fs/fs.h> #include <sys/mman.h> +#include <sys/stat.h> #include <sys/utsname.h> -#ifdef HAVE_BACKTRACE_SUPPORT -#include <execinfo.h> -#endif +#include <dirent.h> +#include <inttypes.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -17,24 +18,8 @@ #include <linux/log2.h> #include <linux/time64.h> #include <unistd.h> -#include "callchain.h" #include "strlist.h" -#define CALLCHAIN_PARAM_DEFAULT \ - .mode = CHAIN_GRAPH_ABS, \ - .min_percent = 0.5, \ - .order = ORDER_CALLEE, \ - .key = CCKEY_FUNCTION, \ - .value = CCVAL_PERCENT, \ - -struct callchain_param callchain_param = { - CALLCHAIN_PARAM_DEFAULT -}; - -struct callchain_param callchain_param_default = { - CALLCHAIN_PARAM_DEFAULT -}; - /* * XXX We need to find a better place for these things... */ @@ -269,28 +254,6 @@ int copyfile(const char *from, const char *to) return copyfile_mode(from, to, 0755); } -unsigned long convert_unit(unsigned long value, char *unit) -{ - *unit = ' '; - - if (value > 1000) { - value /= 1000; - *unit = 'K'; - } - - if (value > 1000) { - value /= 1000; - *unit = 'M'; - } - - if (value > 1000) { - value /= 1000; - *unit = 'G'; - } - - return value; -} - static ssize_t ion(bool is_read, int fd, void *buf, size_t n) { void *buf_start = buf; @@ -372,42 +335,6 @@ int hex2u64(const char *ptr, u64 *long_val) return p - ptr; } -/* Obtain a backtrace and print it to stdout. */ -#ifdef HAVE_BACKTRACE_SUPPORT -void dump_stack(void) -{ - void *array[16]; - size_t size = backtrace(array, ARRAY_SIZE(array)); - char **strings = backtrace_symbols(array, size); - size_t i; - - printf("Obtained %zd stack frames.\n", size); - - for (i = 0; i < size; i++) - printf("%s\n", strings[i]); - - free(strings); -} -#else -void dump_stack(void) {} -#endif - -void sighandler_dump_stack(int sig) -{ - psignal(sig, "perf"); - dump_stack(); - signal(sig, SIG_DFL); - raise(sig); -} - -int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz) -{ - u64 sec = timestamp / NSEC_PER_SEC; - u64 usec = (timestamp % NSEC_PER_SEC) / NSEC_PER_USEC; - - return scnprintf(buf, sz, "%"PRIu64".%06"PRIu64, sec, usec); -} - unsigned long parse_tag_value(const char *str, struct parse_tag *tags) { struct parse_tag *i = tags; @@ -435,108 +362,6 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags) return (unsigned long) -1; } -int get_stack_size(const char *str, unsigned long *_size) -{ - char *endptr; - unsigned long size; - unsigned long max_size = round_down(USHRT_MAX, sizeof(u64)); - - size = strtoul(str, &endptr, 0); - - do { - if (*endptr) - break; - - size = round_up(size, sizeof(u64)); - if (!size || size > max_size) - break; - - *_size = size; - return 0; - - } while (0); - - pr_err("callchain: Incorrect stack dump size (max %ld): %s\n", - max_size, str); - return -1; -} - -int parse_callchain_record(const char *arg, struct callchain_param *param) -{ - char *tok, *name, *saveptr = NULL; - char *buf; - int ret = -1; - - /* We need buffer that we know we can write to. */ - buf = malloc(strlen(arg) + 1); - if (!buf) - return -ENOMEM; - - strcpy(buf, arg); - - tok = strtok_r((char *)buf, ",", &saveptr); - name = tok ? : (char *)buf; - - do { - /* Framepointer style */ - if (!strncmp(name, "fp", sizeof("fp"))) { - if (!strtok_r(NULL, ",", &saveptr)) { - param->record_mode = CALLCHAIN_FP; - ret = 0; - } else - pr_err("callchain: No more arguments " - "needed for --call-graph fp\n"); - break; - - /* Dwarf style */ - } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) { - const unsigned long default_stack_dump_size = 8192; - - ret = 0; - param->record_mode = CALLCHAIN_DWARF; - param->dump_size = default_stack_dump_size; - - tok = strtok_r(NULL, ",", &saveptr); - if (tok) { - unsigned long size = 0; - - ret = get_stack_size(tok, &size); - param->dump_size = size; - } - } else if (!strncmp(name, "lbr", sizeof("lbr"))) { - if (!strtok_r(NULL, ",", &saveptr)) { - param->record_mode = CALLCHAIN_LBR; - ret = 0; - } else - pr_err("callchain: No more arguments " - "needed for --call-graph lbr\n"); - break; - } else { - pr_err("callchain: Unknown --call-graph option " - "value: %s\n", arg); - break; - } - - } while (0); - - free(buf); - return ret; -} - -const char *get_filename_for_perf_kvm(void) -{ - const char *filename; - - if (perf_host && !perf_guest) - filename = strdup("perf.data.host"); - else if (!perf_host && perf_guest) - filename = strdup("perf.data.guest"); - else - filename = strdup("perf.data.kvm"); - - return filename; -} - int perf_event_paranoid(void) { int value; @@ -696,7 +521,8 @@ const char *perf_tip(const char *dirpath) tips = strlist__new("tips.txt", &conf); if (tips == NULL) - return errno == ENOENT ? NULL : "Tip: get more memory! ;-p"; + return errno == ENOENT ? NULL : + "Tip: check path of tips.txt or get more memory! ;-p"; if (strlist__nr_entries(tips) == 0) goto out; @@ -710,95 +536,3 @@ out: return tip; } - -bool is_regular_file(const char *file) -{ - struct stat st; - - if (stat(file, &st)) - return false; - - return S_ISREG(st.st_mode); -} - -int fetch_current_timestamp(char *buf, size_t sz) -{ - struct timeval tv; - struct tm tm; - char dt[32]; - - if (gettimeofday(&tv, NULL) || !localtime_r(&tv.tv_sec, &tm)) - return -1; - - if (!strftime(dt, sizeof(dt), "%Y%m%d%H%M%S", &tm)) - return -1; - - scnprintf(buf, sz, "%s%02u", dt, (unsigned)tv.tv_usec / 10000); - - return 0; -} - -void print_binary(unsigned char *data, size_t len, - size_t bytes_per_line, print_binary_t printer, - void *extra) -{ - size_t i, j, mask; - - if (!printer) - return; - - bytes_per_line = roundup_pow_of_two(bytes_per_line); - mask = bytes_per_line - 1; - - printer(BINARY_PRINT_DATA_BEGIN, 0, extra); - for (i = 0; i < len; i++) { - if ((i & mask) == 0) { - printer(BINARY_PRINT_LINE_BEGIN, -1, extra); - printer(BINARY_PRINT_ADDR, i, extra); - } - - printer(BINARY_PRINT_NUM_DATA, data[i], extra); - - if (((i & mask) == mask) || i == len - 1) { - for (j = 0; j < mask-(i & mask); j++) - printer(BINARY_PRINT_NUM_PAD, -1, extra); - - printer(BINARY_PRINT_SEP, i, extra); - for (j = i & ~mask; j <= i; j++) - printer(BINARY_PRINT_CHAR_DATA, data[j], extra); - for (j = 0; j < mask-(i & mask); j++) - printer(BINARY_PRINT_CHAR_PAD, i, extra); - printer(BINARY_PRINT_LINE_END, -1, extra); - } - } - printer(BINARY_PRINT_DATA_END, -1, extra); -} - -int is_printable_array(char *p, unsigned int len) -{ - unsigned int i; - - if (!p || !len || p[len - 1] != 0) - return 0; - - len--; - - for (i = 0; i < len; i++) { - if (!isprint(p[i]) && !isspace(p[i])) - return 0; - } - return 1; -} - -int unit_number__scnprintf(char *buf, size_t size, u64 n) -{ - char unit[4] = "BKMG"; - int i = 0; - - while (((n / 1024) > 1) && (i < 3)) { - n /= 1024; - i++; - } - - return scnprintf(buf, size, "%" PRIu64 "%c", n, unit[i]); -} |