lkml.org 
[lkml]   [2013]   [Dec]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/4] perf tools: Fix mmap pages rounding to power of 2
    Date
    'next_pow2()' only works for 'unsigned int' but the
    argument is 'unsigned long'. Checking for values
    less than (1 << 31) ensures that 'next_pow2()' is
    not passed a value out of range but lets anything
    else go through unvalidated.

    As a result mmap_pages of zero is used e.g.

    perf record -v -m2147483649 uname
    mmap size 0B
    failed to mmap with 22 (Invalid argument)

    Fixed:

    perf record -m2147483649 uname
    rounding mmap pages size to 17592186044416 bytes (4294967296 pages)
    Invalid argument for --mmap_pages/-m

    Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
    ---
    tools/perf/util/evlist.c | 6 ++++--
    tools/perf/util/util.h | 12 ++++++++++++
    2 files changed, 16 insertions(+), 2 deletions(-)

    diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
    index 98ec96b..af25055 100644
    --- a/tools/perf/util/evlist.c
    +++ b/tools/perf/util/evlist.c
    @@ -734,9 +734,11 @@ static long parse_pages_arg(const char *str, unsigned long min,

    if (pages == 0 && min == 0) {
    /* leave number of pages at 0 */
    - } else if (pages < (1UL << 31) && !is_power_of_2(pages)) {
    + } else if (!is_power_of_2(pages)) {
    /* round pages up to next power of 2 */
    - pages = next_pow2(pages);
    + pages = next_pow2_l(pages);
    + if (!pages)
    + return -EINVAL;
    pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
    pages * page_size, pages);
    }
    diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
    index adb39f2..659abf3 100644
    --- a/tools/perf/util/util.h
    +++ b/tools/perf/util/util.h
    @@ -73,6 +73,7 @@
    #include <sys/ttydefaults.h>
    #include <lk/debugfs.h>
    #include <termios.h>
    +#include <linux/bitops.h>

    extern const char *graph_line;
    extern const char *graph_dotted_line;
    @@ -281,6 +282,17 @@ static inline unsigned next_pow2(unsigned x)
    return 1ULL << (32 - __builtin_clz(x - 1));
    }

    +static inline unsigned long next_pow2_l(unsigned long x)
    +{
    +#if BITS_PER_LONG == 64
    + if (x <= (1UL << 31))
    + return next_pow2(x);
    + return (unsigned long)next_pow2(x >> 32) << 32;
    +#else
    + return next_pow2(x);
    +#endif
    +}
    +
    size_t hex_width(u64 v);
    int hex2u64(const char *ptr, u64 *val);

    --
    1.7.11.7


    \
     
     \ /
      Last update: 2013-12-09 14:21    [W:5.149 / U:0.156 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site