mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/5] include/linux/log2.h warning fix
@ 2018-08-24  2:58 Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 1/5] log2: make order_base_2() behave correctly on const input value zero Andrey Smirnov
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Andrey Smirnov @ 2018-08-24  2:58 UTC (permalink / raw)
  To: barebox; +Cc: andrew.smirnov

Everyone:

This series is result of fixing compiler warnings similar to the one
below:

In file included from drivers/clk/clk-divider.c:22:
include/linux/log2.h:22:1: warning: ignoring attribute ‘noreturn’ because it conflicts with attribute ‘const’ [-Wattributes]
 int ____ilog2_NaN(void);

that I've been observing lately. Technically only the patch by Linus
is really needed, but given that those patches could be applied as-is
pretty easily I "backported" all of the recent kernel changes to
log2.h

Feedback is welcome!

Thanks,
Andrey Smirnov

Andrey Smirnov (1):
  log2: Use fls_long() in __roundup_pow_of_two()

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

Linus Torvalds (1):
  give up on gcc ilog2() constant optimizations

Martin Wilck (1):
  scsi: ilog2: create truly constant version for sparse

Randy Dunlap (1):
  linux/log2.h: fix kernel-doc notation

 include/linux/log2.h | 89 +++++++++++++++++++++++++++-----------------
 1 file changed, 54 insertions(+), 35 deletions(-)

-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] log2: make order_base_2() behave correctly on const input value zero
  2018-08-24  2:58 [PATCH 0/5] include/linux/log2.h warning fix Andrey Smirnov
@ 2018-08-24  2:58 ` Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 2/5] give up on gcc ilog2() constant optimizations Andrey Smirnov
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Andrey Smirnov @ 2018-08-24  2:58 UTC (permalink / raw)
  To: barebox; +Cc: andrew.smirnov

From: Ard Biesheuvel <ard.biesheuvel@linaro.org>

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>
[andrew.smirnov@gmail.com: Applied kernel patch to Barebox as-is]
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 include/linux/log2.h | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/include/linux/log2.h b/include/linux/log2.h
index 36519e3aa..da4f60f94 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -203,6 +203,17 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
  *  ... and so on.
  */
 
-#define order_base_2(n) ilog2(roundup_pow_of_two(n))
+static inline __attribute_const__
+int __order_base_2(unsigned long n)
+{
+	return n > 1 ? ilog2(n - 1) + 1 : 0;
+}
 
+#define order_base_2(n)				\
+(						\
+	__builtin_constant_p(n) ? (		\
+		((n) == 0 || (n) == 1) ? 0 :	\
+		ilog2((n) - 1) + 1) :		\
+	__order_base_2(n)			\
+)
 #endif /* _LINUX_LOG2_H */
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/5] give up on gcc ilog2() constant optimizations
  2018-08-24  2:58 [PATCH 0/5] include/linux/log2.h warning fix Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 1/5] log2: make order_base_2() behave correctly on const input value zero Andrey Smirnov
@ 2018-08-24  2:58 ` Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 3/5] log2: Use fls_long() in __roundup_pow_of_two() Andrey Smirnov
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Andrey Smirnov @ 2018-08-24  2:58 UTC (permalink / raw)
  To: barebox; +Cc: andrew.smirnov

From: Linus Torvalds <torvalds@linux-foundation.org>

gcc-7 has an "optimization" pass that completely screws up, and
generates the code expansion for the (impossible) case of calling
ilog2() with a zero constant, even when the code gcc compiles does not
actually have a zero constant.

And we try to generate a compile-time error for anybody doing ilog2() on
a constant where that doesn't make sense (be it zero or negative).  So
now gcc7 will fail the build due to our sanity checking, because it
created that constant-zero case that didn't actually exist in the source
code.

There's a whole long discussion on the kernel mailing about how to work
around this gcc bug.  The gcc people themselevs have discussed their
"feature" in

   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72785

but it's all water under the bridge, because while it looked at one
point like it would be solved by the time gcc7 was released, that was
not to be.

So now we have to deal with this compiler braindamage.

And the only simple approach seems to be to just delete the code that
tries to warn about bad uses of ilog2().

So now "ilog2()" will just return 0 not just for the value 1, but for
any non-positive value too.

It's not like I can recall anybody having ever actually tried to use
this function on any invalid value, but maybe the sanity check just
meant that such code never made it out in public.

Reported-by: Laura Abbott <labbott@redhat.com>
Cc: John Stultz <john.stultz@linaro.org>,
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[andrew.smirnov@gmail.com: Applied kernel patch to Barebox as-is, but
specifying --exclude=tools/include/linux/log2.h]
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 include/linux/log2.h | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/include/linux/log2.h b/include/linux/log2.h
index da4f60f94..919a22790 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -15,12 +15,6 @@
 #include <linux/types.h>
 #include <linux/bitops.h>
 
-/*
- * deal with unrepresentable constant logarithms
- */
-extern __attribute__((const, noreturn))
-int ____ilog2_NaN(void);
-
 /*
  * non-constant log of base 2 calculators
  * - the arch may override these in asm/bitops.h if they can be implemented
@@ -85,7 +79,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 #define ilog2(n)				\
 (						\
 	__builtin_constant_p(n) ? (		\
-		(n) < 1 ? ____ilog2_NaN() :	\
+		(n) < 2 ? 0 :			\
 		(n) & (1ULL << 63) ? 63 :	\
 		(n) & (1ULL << 62) ? 62 :	\
 		(n) & (1ULL << 61) ? 61 :	\
@@ -148,10 +142,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 		(n) & (1ULL <<  4) ?  4 :	\
 		(n) & (1ULL <<  3) ?  3 :	\
 		(n) & (1ULL <<  2) ?  2 :	\
-		(n) & (1ULL <<  1) ?  1 :	\
-		(n) & (1ULL <<  0) ?  0 :	\
-		____ilog2_NaN()			\
-				   ) :		\
+		1 ) :				\
 	(sizeof(n) <= 4) ?			\
 	__ilog2_u32(n) :			\
 	__ilog2_u64(n)				\
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/5] log2: Use fls_long() in __roundup_pow_of_two()
  2018-08-24  2:58 [PATCH 0/5] include/linux/log2.h warning fix Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 1/5] log2: make order_base_2() behave correctly on const input value zero Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 2/5] give up on gcc ilog2() constant optimizations Andrey Smirnov
@ 2018-08-24  2:58 ` Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 4/5] linux/log2.h: fix kernel-doc notation Andrey Smirnov
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Andrey Smirnov @ 2018-08-24  2:58 UTC (permalink / raw)
  To: barebox; +Cc: andrew.smirnov

Convert __roundup_pow_of_two() to use fls_long() instead of fls() so
the code would be identical to that found in Linux. This fix also
allowed next patch(taken from Linux kernel verbatim) to apply cleanly.

Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 include/linux/log2.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/log2.h b/include/linux/log2.h
index 919a22790..c373295f3 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -54,7 +54,7 @@ bool is_power_of_2(unsigned long n)
 static inline __attribute__((const))
 unsigned long __roundup_pow_of_two(unsigned long n)
 {
-	return 1UL << fls(n - 1);
+	return 1UL << fls_long(n - 1);
 }
 
 /*
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/5] linux/log2.h: fix kernel-doc notation
  2018-08-24  2:58 [PATCH 0/5] include/linux/log2.h warning fix Andrey Smirnov
                   ` (2 preceding siblings ...)
  2018-08-24  2:58 ` [PATCH 3/5] log2: Use fls_long() in __roundup_pow_of_two() Andrey Smirnov
@ 2018-08-24  2:58 ` Andrey Smirnov
  2018-08-24  2:58 ` [PATCH 5/5] scsi: ilog2: create truly constant version for sparse Andrey Smirnov
  2018-08-24  8:23 ` [PATCH 0/5] include/linux/log2.h warning fix Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Andrey Smirnov @ 2018-08-24  2:58 UTC (permalink / raw)
  To: barebox; +Cc: andrew.smirnov

From: Randy Dunlap <rdunlap@infradead.org>

Fix <linux/log2.h> kernel-doc:
- Add kernel-doc notation to some functions.
- Fix kernel-doc notation in function parameters.

Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
[andrew.smirnov@gmail.com: Applied kernel patch to Barebox as-is]
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 include/linux/log2.h | 42 +++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/include/linux/log2.h b/include/linux/log2.h
index c373295f3..41a1ae010 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -37,19 +37,23 @@ int __ilog2_u64(u64 n)
 }
 #endif
 
-/*
- *  Determine whether some value is a power of two, where zero is
+/**
+ * is_power_of_2() - check if a value is a power of two
+ * @n: the value to check
+ *
+ * Determine whether some value is a power of two, where zero is
  * *not* considered a power of two.
+ * Return: true if @n is a power of 2, otherwise false.
  */
-
 static inline __attribute__((const))
 bool is_power_of_2(unsigned long n)
 {
 	return (n != 0 && ((n & (n - 1)) == 0));
 }
 
-/*
- * round up to nearest power of two
+/**
+ * __roundup_pow_of_two() - round up to nearest power of two
+ * @n: value to round up
  */
 static inline __attribute__((const))
 unsigned long __roundup_pow_of_two(unsigned long n)
@@ -57,8 +61,9 @@ unsigned long __roundup_pow_of_two(unsigned long n)
 	return 1UL << fls_long(n - 1);
 }
 
-/*
- * round down to nearest power of two
+/**
+ * __rounddown_pow_of_two() - round down to nearest power of two
+ * @n: value to round down
  */
 static inline __attribute__((const))
 unsigned long __rounddown_pow_of_two(unsigned long n)
@@ -67,12 +72,12 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 }
 
 /**
- * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
- * @n - parameter
+ * ilog2 - log 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 massive ternary operator construction
  *
  * selects the appropriately-sized optimised version depending on sizeof(n)
  */
@@ -150,7 +155,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 
 /**
  * roundup_pow_of_two - round the given value up to nearest power of two
- * @n - parameter
+ * @n: parameter
  *
  * round the given value up to the nearest power of two
  * - the result is undefined when n == 0
@@ -167,7 +172,7 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 
 /**
  * rounddown_pow_of_two - round the given value down to nearest power of two
- * @n - parameter
+ * @n: parameter
  *
  * round the given value down to the nearest power of two
  * - the result is undefined when n == 0
@@ -180,6 +185,12 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 	__rounddown_pow_of_two(n)		\
  )
 
+static inline __attribute_const__
+int __order_base_2(unsigned long n)
+{
+	return n > 1 ? ilog2(n - 1) + 1 : 0;
+}
+
 /**
  * order_base_2 - calculate the (rounded up) base 2 order of the argument
  * @n: parameter
@@ -193,13 +204,6 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
  *  ob2(5) = 3
  *  ... and so on.
  */
-
-static inline __attribute_const__
-int __order_base_2(unsigned long n)
-{
-	return n > 1 ? ilog2(n - 1) + 1 : 0;
-}
-
 #define order_base_2(n)				\
 (						\
 	__builtin_constant_p(n) ? (		\
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 5/5] scsi: ilog2: create truly constant version for sparse
  2018-08-24  2:58 [PATCH 0/5] include/linux/log2.h warning fix Andrey Smirnov
                   ` (3 preceding siblings ...)
  2018-08-24  2:58 ` [PATCH 4/5] linux/log2.h: fix kernel-doc notation Andrey Smirnov
@ 2018-08-24  2:58 ` Andrey Smirnov
  2018-08-24  8:23 ` [PATCH 0/5] include/linux/log2.h warning fix Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Andrey Smirnov @ 2018-08-24  2:58 UTC (permalink / raw)
  To: barebox; +Cc: andrew.smirnov

From: Martin Wilck <mwilck@suse.com>

Sparse emits errors about ilog2() in array indices because of the use of
__ilog2_32() and __ilog2_64(), rightly so
(https://www.spinics.net/lists/linux-sparse/msg03471.html).

Create a const_ilog2() variant that works with sparse for this scenario.

(Note: checkpatch.pl complains about missing parentheses, but that
appears to be a false positive. I can get rid of the warning simply by
inserting whitespace, making checkpatch "see" the whole macro).

Signed-off-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
[andrew.smirnov@gmail.com: Applied kernel patch to Barebox as-is]
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 include/linux/log2.h | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/include/linux/log2.h b/include/linux/log2.h
index 41a1ae010..2af7f7786 100644
--- a/include/linux/log2.h
+++ b/include/linux/log2.h
@@ -72,16 +72,13 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 }
 
 /**
- * ilog2 - log base 2 of 32-bit or a 64-bit unsigned value
+ * const_ilog2 - log base 2 of 32-bit or a 64-bit constant 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
- *
- * selects the appropriately-sized optimised version depending on sizeof(n)
+ * Use this where sparse expects a true constant expression, e.g. for array
+ * indices.
  */
-#define ilog2(n)				\
+#define const_ilog2(n)				\
 (						\
 	__builtin_constant_p(n) ? (		\
 		(n) < 2 ? 0 :			\
@@ -147,10 +144,26 @@ unsigned long __rounddown_pow_of_two(unsigned long n)
 		(n) & (1ULL <<  4) ?  4 :	\
 		(n) & (1ULL <<  3) ?  3 :	\
 		(n) & (1ULL <<  2) ?  2 :	\
-		1 ) :				\
-	(sizeof(n) <= 4) ?			\
-	__ilog2_u32(n) :			\
-	__ilog2_u64(n)				\
+		1) :				\
+	-1)
+
+/**
+ * ilog2 - log 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
+ *
+ * selects the appropriately-sized optimised version depending on sizeof(n)
+ */
+#define ilog2(n) \
+( \
+	__builtin_constant_p(n) ?	\
+	const_ilog2(n) :		\
+	(sizeof(n) <= 4) ?		\
+	__ilog2_u32(n) :		\
+	__ilog2_u64(n)			\
  )
 
 /**
-- 
2.17.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5] include/linux/log2.h warning fix
  2018-08-24  2:58 [PATCH 0/5] include/linux/log2.h warning fix Andrey Smirnov
                   ` (4 preceding siblings ...)
  2018-08-24  2:58 ` [PATCH 5/5] scsi: ilog2: create truly constant version for sparse Andrey Smirnov
@ 2018-08-24  8:23 ` Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2018-08-24  8:23 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: barebox

On Thu, Aug 23, 2018 at 07:58:09PM -0700, Andrey Smirnov wrote:
> Everyone:
> 
> This series is result of fixing compiler warnings similar to the one
> below:
> 
> In file included from drivers/clk/clk-divider.c:22:
> include/linux/log2.h:22:1: warning: ignoring attribute ‘noreturn’ because it conflicts with attribute ‘const’ [-Wattributes]
>  int ____ilog2_NaN(void);
> 
> that I've been observing lately. Technically only the patch by Linus
> is really needed, but given that those patches could be applied as-is
> pretty easily I "backported" all of the recent kernel changes to
> log2.h

Applied, thanks

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-08-24  8:24 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-24  2:58 [PATCH 0/5] include/linux/log2.h warning fix Andrey Smirnov
2018-08-24  2:58 ` [PATCH 1/5] log2: make order_base_2() behave correctly on const input value zero Andrey Smirnov
2018-08-24  2:58 ` [PATCH 2/5] give up on gcc ilog2() constant optimizations Andrey Smirnov
2018-08-24  2:58 ` [PATCH 3/5] log2: Use fls_long() in __roundup_pow_of_two() Andrey Smirnov
2018-08-24  2:58 ` [PATCH 4/5] linux/log2.h: fix kernel-doc notation Andrey Smirnov
2018-08-24  2:58 ` [PATCH 5/5] scsi: ilog2: create truly constant version for sparse Andrey Smirnov
2018-08-24  8:23 ` [PATCH 0/5] include/linux/log2.h warning fix Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox