Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

log2: make order_base_2() behave correctly on const input value zero

The function order_base_2() is defined (according to the comment block)
as returning zero on input zero, but subsequently passes the input into
roundup_pow_of_two(), which is explicitly undefined for input zero.

This has gone unnoticed until now, but optimization passes in GCC 7 may
produce constant folded function instances where a constant value of
zero is passed into order_base_2(), resulting in link errors against the
deliberately undefined '____ilog2_NaN'.

So update order_base_2() to adhere to its own documented interface.

[ See

http://marc.info/?l=linux-kernel&m=147672952517795&w=2

and follow-up discussion for more background. The gcc "optimization
pass" is really just broken, but now the GCC trunk problem seems to
have escaped out of just specially built daily images, so we need to
work around it in mainline. - Linus ]

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Ard Biesheuvel and committed by
Linus Torvalds
29905b52 34e00acc

+12 -1
+12 -1
include/linux/log2.h
··· 203 203 * ... and so on. 204 204 */ 205 205 206 - #define order_base_2(n) ilog2(roundup_pow_of_two(n)) 206 + static inline __attribute_const__ 207 + int __order_base_2(unsigned long n) 208 + { 209 + return n > 1 ? ilog2(n - 1) + 1 : 0; 210 + } 207 211 212 + #define order_base_2(n) \ 213 + ( \ 214 + __builtin_constant_p(n) ? ( \ 215 + ((n) == 0 || (n) == 1) ? 0 : \ 216 + ilog2((n) - 1) + 1) : \ 217 + __order_base_2(n) \ 218 + ) 208 219 #endif /* _LINUX_LOG2_H */