* [PATCH] Fix get_order() [try #2]
@ 2007-03-06 18:34 David Howells
2007-03-06 18:37 ` H. Peter Anvin
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: David Howells @ 2007-03-06 18:34 UTC (permalink / raw)
To: torvalds, akpm, benh; +Cc: linux-kernel, hpa, johannes, dhowells
From: David Howells <dhowells@redhat.com>
Provide an ilog2_up() that rounds its result up (ilog2() rounds down).
Fix get_order() to use ilog2_up() not ilog2() to get the correct rounding.
Adjust the documentation surrounding ilog2() and co. to indicate what rounding
they perform.
Fix roundup_pow_of_two(1) to give 1, not 0.
Signed-Off-By: David Howells <dhowells@redhat.com>
---
include/asm-generic/page.h | 14 +++++++++-----
include/linux/log2.h | 20 ++++++++++++++++++--
2 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/include/asm-generic/page.h b/include/asm-generic/page.h
index b55052c..c79dc23 100644
--- a/include/asm-generic/page.h
+++ b/include/asm-generic/page.h
@@ -17,11 +17,15 @@ static inline __attribute__((const))
int __get_order(unsigned long size, int page_shift)
{
#if BITS_PER_LONG == 32 && defined(ARCH_HAS_ILOG2_U32)
- int order = __ilog2_u32(size) - page_shift;
- return order >= 0 ? order : 0;
+ if (size <= (1UL << page_shift))
+ return 0;
+ else
+ return __ilog2_u32(size - 1) + 1 - page_shift;
#elif BITS_PER_LONG == 64 && defined(ARCH_HAS_ILOG2_U64)
- int order = __ilog2_u64(size) - page_shift;
- return order >= 0 ? order : 0;
+ if (size <= (1UL << page_shift))
+ return 0;
+ else
+ return __ilog2_u64(size - 1) + 1 - page_shift;
#else
int order;
@@ -46,7 +50,7 @@ int __get_order(unsigned long size, int page_shift)
#define get_order(n) \
( \
__builtin_constant_p(n) ? \
- ((n < (1UL << PAGE_SHIFT)) ? 0 : ilog2(n) - PAGE_SHIFT) : \
+ ((n < (1UL << PAGE_SHIFT)) ? 0 : ilog2_up(n) - PAGE_SHIFT) : \
__get_order(n, PAGE_SHIFT) \
)
diff --git a/include/linux/log2.h b/include/linux/log2.h
index 57e641e..bc3a0eb 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -70,6 +70,8 @@ unsigned long __roundup_pow_of_two(unsigned long n)
* constant-capable log of base 2 calculation
* - this can be used to initialise global variables from constant data, hence
* the massive ternary operator construction
+ * - the result is rounded down
+ * - the result is undefined when n < 1
*
* selects the appropriately-sized optimised version depending on sizeof(n)
*/
@@ -149,6 +151,20 @@ unsigned long __roundup_pow_of_two(unsigned long n)
)
/**
+ * ilog2_up - rounded up log of base 2 of 32-bit or a 64-bit unsigned value
+ * @n - parameter
+ *
+ * constant-capable log of base 2 calculation
+ * - this can be used to initialise global variables from constant data, hence
+ * the massive ternary operator construction
+ * - the result is rounded up
+ * - the result is undefined when n < 1
+ *
+ * selects the appropriately-sized optimised version depending on sizeof(n)
+ */
+#define ilog2_up(n) ((n) == 1 ? 0 : ilog2((n) - 1) + 1)
+
+/**
* roundup_pow_of_two - round the given value up to nearest power of two
* @n - parameter
*
@@ -159,8 +175,8 @@ unsigned long __roundup_pow_of_two(unsigned long n)
#define roundup_pow_of_two(n) \
( \
__builtin_constant_p(n) ? ( \
- (n == 1) ? 0 : \
- (1UL << (ilog2((n) - 1) + 1)) \
+ (n == 1) ? 1 : \
+ (1UL << ilog2_up(n)) \
) : \
__roundup_pow_of_two(n) \
)
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH] Fix get_order() [try #2]
2007-03-06 18:34 [PATCH] Fix get_order() [try #2] David Howells
@ 2007-03-06 18:37 ` H. Peter Anvin
2007-03-06 18:41 ` David Howells
2007-03-06 18:39 ` H. Peter Anvin
2007-03-06 19:42 ` Alexey Dobriyan
2 siblings, 1 reply; 8+ messages in thread
From: H. Peter Anvin @ 2007-03-06 18:37 UTC (permalink / raw)
To: David Howells; +Cc: torvalds, akpm, benh, linux-kernel, johannes
David Howells wrote:
> From: David Howells <dhowells@redhat.com>
>
> Provide an ilog2_up() that rounds its result up (ilog2() rounds down).
>
> Fix get_order() to use ilog2_up() not ilog2() to get the correct rounding.
>
> Adjust the documentation surrounding ilog2() and co. to indicate what rounding
> they perform.
>
> Fix roundup_pow_of_two(1) to give 1, not 0.
Eh? roundup_pow_of_two(1) should be 0; 2^0 = 1.
-hpa
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix get_order() [try #2]
2007-03-06 18:37 ` H. Peter Anvin
@ 2007-03-06 18:41 ` David Howells
0 siblings, 0 replies; 8+ messages in thread
From: David Howells @ 2007-03-06 18:41 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: torvalds, akpm, benh, linux-kernel, johannes
H. Peter Anvin <hpa@zytor.com> wrote:
> Eh? roundup_pow_of_two(1) should be 0; 2^0 = 1.
Nonono.
roundup_pow_of_two(0) => ?
roundup_pow_of_two(1) => 1
roundup_pow_of_two(2) => 2
roundup_pow_of_two(3) => 4
roundup_pow_of_two(4) => 4
roundup_pow_of_two(5) => 8
roundup_pow_of_two(6) => 8
roundup_pow_of_two(7) => 8
roundup_pow_of_two(8) => 8
roundup_pow_of_two(9) => 16
roundup_pow_of_two(10) => 16
roundup_pow_of_two(11) => 16
...
David
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix get_order() [try #2]
2007-03-06 18:34 [PATCH] Fix get_order() [try #2] David Howells
2007-03-06 18:37 ` H. Peter Anvin
@ 2007-03-06 18:39 ` H. Peter Anvin
2007-03-06 18:47 ` David Howells
2007-03-06 19:42 ` Alexey Dobriyan
2 siblings, 1 reply; 8+ messages in thread
From: H. Peter Anvin @ 2007-03-06 18:39 UTC (permalink / raw)
To: David Howells; +Cc: torvalds, akpm, benh, linux-kernel, johannes
David Howells wrote:
>
> /**
> + * ilog2_up - rounded up log of base 2 of 32-bit or a 64-bit unsigned value
> + * @n - parameter
> + *
> + * constant-capable log of base 2 calculation
> + * - this can be used to initialise global variables from constant data, hence
> + * the massive ternary operator construction
> + * - the result is rounded up
> + * - the result is undefined when n < 1
> + *
> + * selects the appropriately-sized optimised version depending on sizeof(n)
> + */
> +#define ilog2_up(n) ((n) == 1 ? 0 : ilog2((n) - 1) + 1)
> +
Why not just make it ((n) < 1 ? 0 : ...) and make it well-defined for
n == 0?
> +/**
> * roundup_pow_of_two - round the given value up to nearest power of two
> * @n - parameter
> *
> @@ -159,8 +175,8 @@ unsigned long __roundup_pow_of_two(unsigned long n)
> #define roundup_pow_of_two(n) \
> ( \
> __builtin_constant_p(n) ? ( \
> - (n == 1) ? 0 : \
> - (1UL << (ilog2((n) - 1) + 1)) \
> + (n == 1) ? 1 : \
> + (1UL << ilog2_up(n)) \
> ) : \
... then this can be just "1UL << ilog2_up(n)".
[Sorry about previous email. I got confused about what
roundup_pow_of_two() actually does.]
-hpa
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix get_order() [try #2]
2007-03-06 18:39 ` H. Peter Anvin
@ 2007-03-06 18:47 ` David Howells
2007-03-06 18:51 ` H. Peter Anvin
0 siblings, 1 reply; 8+ messages in thread
From: David Howells @ 2007-03-06 18:47 UTC (permalink / raw)
To: H. Peter Anvin; +Cc: torvalds, akpm, benh, linux-kernel, johannes
H. Peter Anvin <hpa@zytor.com> wrote:
> Why not just make it ((n) < 1 ? 0 : ...) and make it well-defined for
> n == 0?
Because log2(0) is -INF or mathematically undefined or something isn't it?
David
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix get_order() [try #2]
2007-03-06 18:47 ` David Howells
@ 2007-03-06 18:51 ` H. Peter Anvin
0 siblings, 0 replies; 8+ messages in thread
From: H. Peter Anvin @ 2007-03-06 18:51 UTC (permalink / raw)
To: David Howells; +Cc: torvalds, akpm, benh, linux-kernel, johannes
David Howells wrote:
> H. Peter Anvin <hpa@zytor.com> wrote:
>
>> Why not just make it ((n) < 1 ? 0 : ...) and make it well-defined for
>> n == 0?
>
> Because log2(0) is -INF or mathematically undefined or something isn't it?
Yes, but it's a *rounding up* function. In this case, it makes sense to
round up 0 to 1. This is, in fact, a common way to handle requests for
zero-byte allocation in order to be able to return a unique address for
each one, so it's not a spurious thing.
-hpa
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Fix get_order() [try #2]
2007-03-06 18:34 [PATCH] Fix get_order() [try #2] David Howells
2007-03-06 18:37 ` H. Peter Anvin
2007-03-06 18:39 ` H. Peter Anvin
@ 2007-03-06 19:42 ` Alexey Dobriyan
2007-03-06 20:01 ` David Howells
2 siblings, 1 reply; 8+ messages in thread
From: Alexey Dobriyan @ 2007-03-06 19:42 UTC (permalink / raw)
To: David Howells; +Cc: torvalds, akpm, benh, linux-kernel, hpa, johannes
On Tue, Mar 06, 2007 at 06:34:26PM +0000, David Howells wrote:
> Provide an ilog2_up() that rounds its result up (ilog2() rounds down).
>
> Fix get_order() to use ilog2_up() not ilog2() to get the correct rounding.
>
> Adjust the documentation surrounding ilog2() and co. to indicate what rounding
> they perform.
>
> Fix roundup_pow_of_two(1) to give 1, not 0.
> --- a/include/asm-generic/page.h
> +++ b/include/asm-generic/page.h
> @@ -17,11 +17,15 @@ static inline __attribute__((const))
> int __get_order(unsigned long size, int page_shift)
> {
> #if BITS_PER_LONG == 32 && defined(ARCH_HAS_ILOG2_U32)
There is no such thing except on FRV, where it's redundant.
CONFIG_ARCH_HAS_ILOG2_U32
^^^^^^
> - int order = __ilog2_u32(size) - page_shift;
> - return order >= 0 ? order : 0;
> + if (size <= (1UL << page_shift))
> + return 0;
> + else
> + return __ilog2_u32(size - 1) + 1 - page_shift;
> #elif BITS_PER_LONG == 64 && defined(ARCH_HAS_ILOG2_U64)
ditto
> - int order = __ilog2_u64(size) - page_shift;
> - return order >= 0 ? order : 0;
> + if (size <= (1UL << page_shift))
> + return 0;
> + else
> + return __ilog2_u64(size - 1) + 1 - page_shift;
> #else
> int order;
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH] Fix get_order() [try #2]
2007-03-06 19:42 ` Alexey Dobriyan
@ 2007-03-06 20:01 ` David Howells
0 siblings, 0 replies; 8+ messages in thread
From: David Howells @ 2007-03-06 20:01 UTC (permalink / raw)
To: Alexey Dobriyan; +Cc: torvalds, akpm, benh, linux-kernel, hpa, johannes
Alexey Dobriyan <adobriyan@gmail.com> wrote:
> > #if BITS_PER_LONG == 32 && defined(ARCH_HAS_ILOG2_U32)
>
> There is no such thing except on FRV, where it's redundant.
Redundant in what way?
> CONFIG_ARCH_HAS_ILOG2_U32
> ^^^^^^
Grrr. Thanks for spotting that.
> > #elif BITS_PER_LONG == 64 && defined(ARCH_HAS_ILOG2_U64)
>
> ditto
Ditto.
David
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2007-03-06 20:02 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-06 18:34 [PATCH] Fix get_order() [try #2] David Howells
2007-03-06 18:37 ` H. Peter Anvin
2007-03-06 18:41 ` David Howells
2007-03-06 18:39 ` H. Peter Anvin
2007-03-06 18:47 ` David Howells
2007-03-06 18:51 ` H. Peter Anvin
2007-03-06 19:42 ` Alexey Dobriyan
2007-03-06 20:01 ` David Howells
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox