13 Dec, 2011

1 commit

  • Exactly like roundup_pow_of_two(1), the rounddown version was buggy for
    the case of a compile-time constant '1' argument. Probably because it
    originated from the same code, sharing history with the roundup version
    from before the bugfix (for that one, see commit 1a06a52ee1b0: "Fix
    roundup_pow_of_two(1)").

    However, unlike the roundup version, the fix for rounddown is to just
    remove the broken special case entirely. It's simply not needed - the
    generic code

    1UL << ilog2(n)

    does the right thing for the constant '1' argment too. The only reason
    roundup needed that special case was because rounding up does so by
    subtracting one from the argument (and then adding one to the result)
    causing the obvious problems with "ilog2(0)".

    But rounddown doesn't do any of that, since ilog2() naturally truncates
    (ie "rounds down") to the right rounded down value. And without the
    ilog2(0) case, there's no reason for the special case that had the wrong
    value.

    tl;dr: rounddown_pow_of_two(1) should be 1, not 0.

    Acked-by: Dmitry Torokhov
    Cc: stable@kernel.org
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

07 Feb, 2008

1 commit


17 Oct, 2007

1 commit

  • To go along with the existing "roundup_pow_of_two" routine, add one for
    rounding down since that operation appears to crop up on a regular basis in
    the source tree.

    [m.kozlowski@tuxland.pl: fix unbalanced parentheses]
    Signed-off-by: Robert P. J. Day
    Signed-off-by: Mariusz Kozlowski
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Robert P. J. Day
     

19 May, 2007

1 commit

  • 1 is a power of two, therefore roundup_pow_of_two(1) should return 1. It does
    in case the argument is a variable but in case it's a constant it behaves
    wrong and returns 0. Probably nobody ever did it so this was never noticed.

    Signed-off-by: Rolf Eike Beer
    Signed-off-by: Linus Torvalds

    Rolf Eike Beer
     

18 Feb, 2007

1 commit


07 Feb, 2007

1 commit


09 Dec, 2006

2 commits

  • Alter roundup_pow_of_two() so that it can make use of ilog2() on a constant to
    produce a constant value, retaining the ability for an arch to override it in
    the non-const case.

    This permits the function to be used to initialise variables.

    Signed-off-by: David Howells
    Cc: Benjamin Herrenschmidt
    Cc: Paul Mackerras
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells
     
  • This facility provides three entry points:

    ilog2() Log base 2 of unsigned long
    ilog2_u32() Log base 2 of u32
    ilog2_u64() Log base 2 of u64

    These facilities can either be used inside functions on dynamic data:

    int do_something(long q)
    {
    ...;
    y = ilog2(x)
    ...;
    }

    Or can be used to statically initialise global variables with constant values:

    unsigned n = ilog2(27);

    When performing static initialisation, the compiler will report "error:
    initializer element is not constant" if asked to take a log of zero or of
    something not reducible to a constant. They treat negative numbers as
    unsigned.

    When not dealing with a constant, they fall back to using fls() which permits
    them to use arch-specific log calculation instructions - such as BSR on
    x86/x86_64 or SCAN on FRV - if available.

    [akpm@osdl.org: MMC fix]
    Signed-off-by: David Howells
    Cc: Benjamin Herrenschmidt
    Cc: Paul Mackerras
    Cc: Herbert Xu
    Cc: David Howells
    Cc: Wojtek Kaniewski
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells