perf evlist: Refactor mmap_pages parsing
authorDavid Ahern <dsahern@gmail.com>
Tue, 12 Nov 2013 14:46:55 +0000 (07:46 -0700)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 12 Nov 2013 19:33:22 +0000 (16:33 -0300)
Logic will be re-used for the out-pages argument for mmap based writes
in perf-record.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1384267617-3446-4-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/evlist.c

index fb4727d3df85226b78e779345d4a1903582d7e29..cb19044601bb3d797d5a9a7c760944fc5ac4e955 100644 (file)
@@ -705,10 +705,9 @@ static size_t perf_evlist__mmap_size(unsigned long pages)
        return (pages + 1) * page_size;
 }
 
-int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
-                                 int unset __maybe_unused)
+static long parse_pages_arg(const char *str, unsigned long min,
+                           unsigned long max)
 {
-       unsigned int *mmap_pages = opt->value;
        unsigned long pages, val;
        static struct parse_tag tags[] = {
                { .tag  = 'B', .mult = 1       },
@@ -719,7 +718,7 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
        };
 
        if (str == NULL)
-               return -1;
+               return -EINVAL;
 
        val = parse_tag_value(str, tags);
        if (val != (unsigned long) -1) {
@@ -729,20 +728,38 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
                /* 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;
-               }
+               if (*eptr != '\0')
+                       return -EINVAL;
        }
 
-       if (pages < (1UL << 31) && !is_power_of_2(pages)) {
+       if ((pages == 0) && (min == 0)) {
+               /* leave number of pages at 0 */
+       } else if (pages < (1UL << 31) && !is_power_of_2(pages)) {
+               /* round pages up to next power of 2 */
                pages = next_pow2(pages);
                pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
                        pages * page_size, pages);
        }
 
-       if (pages > UINT_MAX || pages > SIZE_MAX / page_size) {
-               pr_err("--mmap_pages/-m value too big\n");
+       if (pages > max)
+               return -EINVAL;
+
+       return pages;
+}
+
+int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
+                                 int unset __maybe_unused)
+{
+       unsigned int *mmap_pages = opt->value;
+       unsigned long max = UINT_MAX;
+       long pages;
+
+       if (max < SIZE_MAX / page_size)
+               max = SIZE_MAX / page_size;
+
+       pages = parse_pages_arg(str, 1, max);
+       if (pages < 0) {
+               pr_err("Invalid argument for --mmap_pages/-m\n");
                return -1;
        }