From 41d0d933494ce10eb77758a1168b08e317c42e8e Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Mon, 19 Dec 2011 08:39:32 -0500 Subject: [PATCH] perf: builtin-record: Document and check that mmap_pages must be a power of two. Now that we automatically point users at it, let's provide them some guidance so that they hopefully don't just get mysterious EINVAL's from the kernel. Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1324301972-22740-4-git-send-email-nelhage@nelhage.com Signed-off-by: Nelson Elhage [ committer note: Made it work after 50a682c ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 2 +- tools/perf/builtin-record.c | 3 +++ tools/perf/util/evlist.c | 2 ++ tools/perf/util/util.h | 11 +++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 5a520f825295..2937f7e14bb7 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -89,7 +89,7 @@ OPTIONS -m:: --mmap-pages=:: - Number of mmap data pages. + Number of mmap data pages. Must be a power of two. -g:: --call-graph:: diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 56bb4476e3ba..e873ae2dd54c 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -279,6 +279,9 @@ try_again: "/proc/sys/kernel/perf_event_mlock_kb,\n" "or try again with a smaller value of -m/--mmap_pages.\n" "(current value: %d)\n", opts->mmap_pages); + else if (!is_power_of_2(opts->mmap_pages)) + die("--mmap_pages/-m value must be a power of two."); + die("failed to mmap with %d (%s)\n", errno, strerror(errno)); } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 963d63dde457..fa1837088ca8 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -563,6 +563,8 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, /* 512 kiB: default amount of unprivileged mlocked memory */ if (pages == UINT_MAX) pages = (512 * 1024) / page_size; + else if (!is_power_of_2(pages)) + return -EINVAL; mask = pages * page_size - 1; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 0128906bac88..37be34dff798 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -245,4 +245,15 @@ int readn(int fd, void *buf, size_t size); #define _STR(x) #x #define STR(x) _STR(x) +/* + * Determine whether some value is a power of two, where zero is + * *not* considered a power of two. + */ + +static inline __attribute__((const)) +bool is_power_of_2(unsigned long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} + #endif