From 89fe808ae777728da6e1d78b7d13562792310d17 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 30 Sep 2013 12:07:11 +0200 Subject: tools/perf: Standardize feature support define names to: HAVE_{FEATURE}_SUPPORT Standardize all the feature flags based on the HAVE_{FEATURE}_SUPPORT naming convention: HAVE_ARCH_X86_64_SUPPORT HAVE_BACKTRACE_SUPPORT HAVE_CPLUS_DEMANGLE_SUPPORT HAVE_DWARF_SUPPORT HAVE_ELF_GETPHDRNUM_SUPPORT HAVE_GTK2_SUPPORT HAVE_GTK_INFO_BAR_SUPPORT HAVE_LIBAUDIT_SUPPORT HAVE_LIBELF_MMAP_SUPPORT HAVE_LIBELF_SUPPORT HAVE_LIBNUMA_SUPPORT HAVE_LIBUNWIND_SUPPORT HAVE_ON_EXIT_SUPPORT HAVE_PERF_REGS_SUPPORT HAVE_SLANG_SUPPORT HAVE_STRLCPY_SUPPORT Cc: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Namhyung Kim Cc: David Ahern Cc: Jiri Olsa Link: http://lkml.kernel.org/n/tip-u3zvqejddfZhtrbYbfhi3spa@git.kernel.org Signed-off-by: Ingo Molnar --- tools/perf/util/util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf/util/util.c') diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 6d17b18e915..ccfdeb62f57 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -1,7 +1,7 @@ #include "../perf.h" #include "util.h" #include -#ifdef BACKTRACE_SUPPORT +#ifdef HAVE_BACKTRACE_SUPPORT #include #endif #include @@ -204,7 +204,7 @@ int hex2u64(const char *ptr, u64 *long_val) } /* Obtain a backtrace and print it to stdout. */ -#ifdef BACKTRACE_SUPPORT +#ifdef HAVE_BACKTRACE_SUPPORT void dump_stack(void) { void *array[16]; -- cgit v1.2.3-70-g09d2 From 27050f530dc4fd88dc93d85c177e000efe970d12 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 1 Sep 2013 12:36:13 +0200 Subject: perf tools: Add possibility to specify mmap size Adding possibility to specify mmap size via -m/--mmap-pages by appending unit size character (B/K/M/G) to the number, like: $ perf record -m 8K ls $ perf record -m 2M ls The size is rounded up appropriately to follow perf mmap restrictions. If no unit is specified the number provides pages as of now, like: $ perf record -m 8 ls Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1378031796-17892-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-kvm.txt | 4 +++- tools/perf/Documentation/perf-record.txt | 4 +++- tools/perf/Documentation/perf-top.txt | 4 +++- tools/perf/Documentation/perf-trace.txt | 4 +++- tools/perf/util/evlist.c | 32 ++++++++++++++++++++++++++------ tools/perf/util/util.c | 25 +++++++++++++++++++++++++ tools/perf/util/util.h | 14 ++++++++++++++ 7 files changed, 77 insertions(+), 10 deletions(-) (limited to 'tools/perf/util/util.c') diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt index ac84db2d233..6a06cefe964 100644 --- a/tools/perf/Documentation/perf-kvm.txt +++ b/tools/perf/Documentation/perf-kvm.txt @@ -109,7 +109,9 @@ STAT LIVE OPTIONS -m:: --mmap-pages=:: - Number of mmap data pages. Must be a power of two. + Number of mmap data pages (must be a power of two) or size + specification with appended unit character - B/K/M/G. The + size is rounded up to have nearest pages power of two value. -a:: --all-cpus:: diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index f732eaa6a50..f10ab63576d 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -87,7 +87,9 @@ OPTIONS -m:: --mmap-pages=:: - Number of mmap data pages. Must be a power of two. + Number of mmap data pages (must be a power of two) or size + specification with appended unit character - B/K/M/G. The + size is rounded up to have nearest pages power of two value. -g:: --call-graph:: diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 6d70fbfe28a..f65777c1f72 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -68,7 +68,9 @@ Default is to monitor all CPUS. -m :: --mmap-pages=:: - Number of mmapped data pages. + Number of mmap data pages (must be a power of two) or size + specification with appended unit character - B/K/M/G. The + size is rounded up to have nearest pages power of two value. -p :: --pid=:: diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 37773854d5c..7f70d3640ed 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -59,7 +59,9 @@ OPTIONS -m:: --mmap-pages=:: - Number of mmap data pages. Must be a power of two. + Number of mmap data pages (must be a power of two) or size + specification with appended unit character - B/K/M/G. The + size is rounded up to have nearest pages power of two value. -C:: --cpu:: diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4283f49ca0a..d21ab081292 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -687,14 +687,33 @@ static size_t perf_evlist__mmap_size(unsigned long pages) int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, int unset __maybe_unused) { - unsigned int pages, *mmap_pages = opt->value; + unsigned int pages, val, *mmap_pages = opt->value; size_t size; - char *eptr; + static struct parse_tag tags[] = { + { .tag = 'B', .mult = 1 }, + { .tag = 'K', .mult = 1 << 10 }, + { .tag = 'M', .mult = 1 << 20 }, + { .tag = 'G', .mult = 1 << 30 }, + { .tag = 0 }, + }; - pages = strtoul(str, &eptr, 10); - if (*eptr != '\0') { - pr_err("failed to parse --mmap_pages/-m value\n"); - return -1; + val = parse_tag_value(str, tags); + if (val != (unsigned int) -1) { + /* we got file size value */ + pages = PERF_ALIGN(val, page_size) / page_size; + if (!is_power_of_2(pages)) { + pages = next_pow2(pages); + pr_info("rounding mmap pages size to %u (%u pages)\n", + pages * page_size, pages); + } + } else { + /* we got pages count value */ + char *eptr; + pages = strtoul(str, &eptr, 10); + if (*eptr != '\0') { + pr_err("failed to parse --mmap_pages/-m value\n"); + return -1; + } } size = perf_evlist__mmap_size(pages); @@ -738,6 +757,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, evlist->overwrite = overwrite; evlist->mmap_len = perf_evlist__mmap_size(pages); + pr_debug("mmap size %luB\n", evlist->mmap_len); mask = evlist->mmap_len - page_size - 1; list_for_each_entry(evsel, &evlist->entries, node) { diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index ccfdeb62f57..ab71d621680 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -361,3 +361,28 @@ int parse_nsec_time(const char *str, u64 *ptime) *ptime = time_sec * NSEC_PER_SEC + time_nsec; return 0; } + +unsigned long parse_tag_value(const char *str, struct parse_tag *tags) +{ + struct parse_tag *i = tags; + + while (i->tag) { + char *s; + + s = strchr(str, i->tag); + if (s) { + unsigned long int value; + char *endptr; + + value = strtoul(str, &endptr, 10); + if (s != endptr) + break; + + value *= i->mult; + return value; + } + i++; + } + + return (unsigned long) -1; +} diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index a5353594904..c29ecaabf46 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -270,6 +270,13 @@ bool is_power_of_2(unsigned long n) return (n != 0 && ((n & (n - 1)) == 0)); } +static inline unsigned next_pow2(unsigned x) +{ + if (!x) + return 1; + return 1ULL << (32 - __builtin_clz(x - 1)); +} + size_t hex_width(u64 v); int hex2u64(const char *ptr, u64 *val); @@ -281,4 +288,11 @@ void dump_stack(void); extern unsigned int page_size; void get_term_dimensions(struct winsize *ws); + +struct parse_tag { + char tag; + int mult; +}; + +unsigned long parse_tag_value(const char *str, struct parse_tag *tags); #endif /* GIT_COMPAT_UTIL_H */ -- cgit v1.2.3-70-g09d2 From 9a17d7268d71674f0bbff6821f7d8e6dc0ece19a Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 14 Oct 2013 13:43:41 +0300 Subject: perf tools: Add copyfile_mode() Add a function to copy a file specifying the permissions to use for the created file. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1381747424-3557-5-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/util.c | 18 +++++++++++++----- tools/perf/util/util.h | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'tools/perf/util/util.c') diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index ab71d621680..8dc8cf39f4e 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -55,17 +55,20 @@ int mkdir_p(char *path, mode_t mode) return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; } -static int slow_copyfile(const char *from, const char *to) +static int slow_copyfile(const char *from, const char *to, mode_t mode) { - int err = 0; + int err = -1; char *line = NULL; size_t n; FILE *from_fp = fopen(from, "r"), *to_fp; + mode_t old_umask; if (from_fp == NULL) goto out; + old_umask = umask(mode ^ 0777); to_fp = fopen(to, "w"); + umask(old_umask); if (to_fp == NULL) goto out_fclose_from; @@ -82,7 +85,7 @@ out: return err; } -int copyfile(const char *from, const char *to) +int copyfile_mode(const char *from, const char *to, mode_t mode) { int fromfd, tofd; struct stat st; @@ -93,13 +96,13 @@ int copyfile(const char *from, const char *to) goto out; if (st.st_size == 0) /* /proc? do it slowly... */ - return slow_copyfile(from, to); + return slow_copyfile(from, to, mode); fromfd = open(from, O_RDONLY); if (fromfd < 0) goto out; - tofd = creat(to, 0755); + tofd = creat(to, mode); if (tofd < 0) goto out_close_from; @@ -121,6 +124,11 @@ out: return err; } +int copyfile(const char *from, const char *to) +{ + return copyfile_mode(from, to, 0755); +} + unsigned long convert_unit(unsigned long value, char *unit) { *unit = ' '; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 1f06ba44cd5..42dfba70fbf 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -243,6 +243,7 @@ static inline int sane_case(int x, int high) int mkdir_p(char *path, mode_t mode); int copyfile(const char *from, const char *to); +int copyfile_mode(const char *from, const char *to, mode_t mode); s64 perf_atoll(const char *str); char **argv_split(const char *str, int *argcp); -- cgit v1.2.3-70-g09d2 From 97a07f10c38064dea492794c99445f6260afcdc1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 17 Oct 2013 16:33:43 -0300 Subject: perf tools: Introduce filename__read_int helper Just opens a file and calls atoi() in at most its first 64 bytes. To read things like /proc/sys/kernel/perf_event_paranoid. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-669q04c5tou5pnt8jtiz6y2r@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/util.c | 17 +++++++++++++++++ tools/perf/util/util.h | 2 ++ 2 files changed, 19 insertions(+) (limited to 'tools/perf/util/util.c') diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 8dc8cf39f4e..c25e57b3acb 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -394,3 +394,20 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags) return (unsigned long) -1; } + +int filename__read_int(const char *filename, int *value) +{ + char line[64]; + int fd = open(filename, O_RDONLY), err = -1; + + if (fd < 0) + return -1; + + if (read(fd, line, sizeof(line)) > 0) { + *value = atoi(line); + err = 0; + } + + close(fd); + return err; +} diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 42dfba70fbf..c8f362daba8 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -305,4 +305,6 @@ struct dso; char *get_srcline(struct dso *dso, unsigned long addr); void free_srcline(char *srcline); + +int filename__read_int(const char *filename, int *value); #endif /* GIT_COMPAT_UTIL_H */ -- cgit v1.2.3-70-g09d2 From 56921becdd1eb0720603fc2e6e4c7f518196d917 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 22 Oct 2013 10:34:17 +0300 Subject: perf tools: Do not accept parse_tag_value() overflow parse_tag_value() accepts an "unsigned long" and multiplies it according to a tag character. Do not accept the value if the multiplication overflows. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1382427258-17495-14-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools/perf/util/util.c') diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index c25e57b3acb..28a0a89c1f7 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -386,6 +386,8 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags) if (s != endptr) break; + if (value > ULONG_MAX / i->mult) + break; value *= i->mult; return value; } -- cgit v1.2.3-70-g09d2