Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1392533 > unrolled thread
| Started by | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| First post | 2016-05-02 23:50 +0200 |
| Last post | 2016-05-03 08:40 +0200 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v2] byteswap: try to avoid __builtin_constant_p gcc bug Arnd Bergmann <arnd@arndb.de> - 2016-05-02 23:50 +0200
Re: [PATCH v2] byteswap: try to avoid __builtin_constant_p gcc bug Andrew Morton <akpm@linux-foundation.org> - 2016-05-03 01:10 +0200
Re: [PATCH v2] byteswap: try to avoid __builtin_constant_p gcc bug Arnd Bergmann <arnd@arndb.de> - 2016-05-03 01:20 +0200
Re: [PATCH v2] byteswap: try to avoid __builtin_constant_p gcc bug Andrew Morton <akpm@linux-foundation.org> - 2016-05-03 01:40 +0200
Re: [PATCH v2] byteswap: try to avoid __builtin_constant_p gcc bug Arnd Bergmann <arnd@arndb.de> - 2016-05-03 08:40 +0200
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-05-02 23:50 +0200 |
| Subject | [PATCH v2] byteswap: try to avoid __builtin_constant_p gcc bug |
| Message-ID | <rutT5-3cr-19@gated-at.bofh.it> |
This is another attempt to avoid a regression in wwn_to_u64() after
that started using get_unaligned_be64(), which in turn ran into a
bug on gcc-4.9 through 6.1.
The regression got introduced due to the combination of two
separate workarounds (e3bde9568d99 and ef3fb2422ffe) that each
try to sidestep distinct problems with gcc behavior (code growth
and increased stack usage). Unfortunately after both have been
applied, a more series gcc bug has been uncovered, leading to
incorrect object code that discards part of a function and
causes undefined behavior.
As part of this problem is how __builtin_constant_p gets evaluated
on an argument passed by reference into an inline function, this
avoids the use of __builtin_constant_p() for all architectures
that set CONFIG_ARCH_USE_BUILTIN_BSWAP. Most architectures do not
set ARCH_SUPPORTS_OPTIMIZED_INLINING, which means they probably
do not suffer from the problem in the qla2xxx driver, but they
might still run into it elsewhere.
Both of the original workarounds were only merged in the 4.6 kernel,
and the bug that is fixed by this patch should only appear if
both are there, so we probably don't need to backport the fix.
On the other hand, it works by simplifying the code path and
should not have any negative effects.
Link: https://lkml.org/lkml/headers/2016/4/12/1103
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66122
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70232
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646
Fixes: e3bde9568d99 ("include/linux/unaligned: force inlining of byteswap operations")
Fixes: ef3fb2422ffe ("scsi: fc: use get/put_unaligned64 for wwn access")
Tested-by: Josh Poimboeuf <jpoimboe@redhat.com> # on gcc-5.3
Tested-by: Quinn Tran <quinn.tran@qlogic.com>
Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
----
This contains the extra cast to fix up 64-bit builds, and has
an expanded changelog, compared to the original version.
diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h
index 3f10e5317b46..de56fd54428d 100644
--- a/include/uapi/linux/swab.h
+++ b/include/uapi/linux/swab.h
@@ -45,9 +45,7 @@
static inline __attribute_const__ __u16 __fswab16(__u16 val)
{
-#ifdef __HAVE_BUILTIN_BSWAP16__
- return __builtin_bswap16(val);
-#elif defined (__arch_swab16)
+#if defined (__arch_swab16)
return __arch_swab16(val);
#else
return ___constant_swab16(val);
@@ -56,9 +54,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val)
static inline __attribute_const__ __u32 __fswab32(__u32 val)
{
-#ifdef __HAVE_BUILTIN_BSWAP32__
- return __builtin_bswap32(val);
-#elif defined(__arch_swab32)
+#if defined(__arch_swab32)
return __arch_swab32(val);
#else
return ___constant_swab32(val);
@@ -67,9 +63,7 @@ static inline __attribute_const__ __u32 __fswab32(__u32 val)
static inline __attribute_const__ __u64 __fswab64(__u64 val)
{
-#ifdef __HAVE_BUILTIN_BSWAP64__
- return __builtin_bswap64(val);
-#elif defined (__arch_swab64)
+#if defined (__arch_swab64)
return __arch_swab64(val);
#elif defined(__SWAB_64_THRU_32__)
__u32 h = val >> 32;
@@ -102,28 +96,40 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val)
* __swab16 - return a byteswapped 16-bit value
* @x: value to byteswap
*/
+#ifdef __HAVE_BUILTIN_BSWAP16__
+#define __swab16(x) __builtin_bswap16((__u16)(x))
+#else
#define __swab16(x) \
(__builtin_constant_p((__u16)(x)) ? \
___constant_swab16(x) : \
__fswab16(x))
+#endif
/**
* __swab32 - return a byteswapped 32-bit value
* @x: value to byteswap
*/
+#ifdef __HAVE_BUILTIN_BSWAP32__
+#define __swab32(x) __builtin_bswap32((__u32)(x))
+#else
#define __swab32(x) \
(__builtin_constant_p((__u32)(x)) ? \
___constant_swab32(x) : \
__fswab32(x))
+#endif
/**
* __swab64 - return a byteswapped 64-bit value
* @x: value to byteswap
*/
+#ifdef __HAVE_BUILTIN_BSWAP64__
+#define __swab64(x) (__u64)__builtin_bswap64((__u64)(x))
+#else
#define __swab64(x) \
(__builtin_constant_p((__u64)(x)) ? \
___constant_swab64(x) : \
__fswab64(x))
+#endif
/**
* __swahw32 - return a word-swapped 32-bit value
[toc] | [next] | [standalone]
| From | Andrew Morton <akpm@linux-foundation.org> |
|---|---|
| Date | 2016-05-03 01:10 +0200 |
| Message-ID | <ruv8u-4zr-3@gated-at.bofh.it> |
| In reply to | #1392533 |
On Mon, 02 May 2016 23:48:19 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > This is another attempt to avoid a regression in wwn_to_u64() after > that started using get_unaligned_be64(), which in turn ran into a > bug on gcc-4.9 through 6.1. I'm still getting a couple screenfuls of things like net/tipc/name_distr.c: In function 'tipc_named_process_backlog': net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 3 has type 'unsigned int' net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 4 has type 'unsigned int' net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'unsigned int' net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 7 has type 'unsigned int'
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-05-03 01:20 +0200 |
| Message-ID | <ruvi9-4En-3@gated-at.bofh.it> |
| In reply to | #1392560 |
On Monday 02 May 2016 16:02:18 Andrew Morton wrote: > On Mon, 02 May 2016 23:48:19 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > > > This is another attempt to avoid a regression in wwn_to_u64() after > > that started using get_unaligned_be64(), which in turn ran into a > > bug on gcc-4.9 through 6.1. > > I'm still getting a couple screenfuls of things like > > net/tipc/name_distr.c: In function 'tipc_named_process_backlog': > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 3 has type 'unsigned int' > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 4 has type 'unsigned int' > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'unsigned int' > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 7 has type 'unsigned int' I've built a few thousand kernels (arm32 with gcc-6.1) with the patch applied, but didn't see this one. What target architecture and compiler version produced this? Does it go away if you add a (__u32) cast? I don't even know what the warning is trying to tell me. Arnd
[toc] | [prev] | [next] | [standalone]
| From | Andrew Morton <akpm@linux-foundation.org> |
|---|---|
| Date | 2016-05-03 01:40 +0200 |
| Message-ID | <ruvBw-4Uv-17@gated-at.bofh.it> |
| In reply to | #1392563 |
On Tue, 03 May 2016 01:10:16 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > On Monday 02 May 2016 16:02:18 Andrew Morton wrote: > > On Mon, 02 May 2016 23:48:19 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > > > > > This is another attempt to avoid a regression in wwn_to_u64() after > > > that started using get_unaligned_be64(), which in turn ran into a > > > bug on gcc-4.9 through 6.1. > > > > I'm still getting a couple screenfuls of things like > > > > net/tipc/name_distr.c: In function 'tipc_named_process_backlog': > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 3 has type 'unsigned int' > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 4 has type 'unsigned int' > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'unsigned int' > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 7 has type 'unsigned int' > > I've built a few thousand kernels (arm32 with gcc-6.1) with the patch applied, > but didn't see this one. What target architecture and compiler version produced > this? Does it go away if you add a (__u32) cast? I don't even know what the > warning is trying to tell me. heh, I didn't actually read it. Hopefully we can write this off as a gcc-4.4.4 glitch. 4.8.4 is OK.
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-05-03 08:40 +0200 |
| Message-ID | <ruC9Y-2UG-7@gated-at.bofh.it> |
| In reply to | #1392569 |
On Monday 02 May 2016 16:32:25 Andrew Morton wrote: > On Tue, 03 May 2016 01:10:16 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > > > On Monday 02 May 2016 16:02:18 Andrew Morton wrote: > > > On Mon, 02 May 2016 23:48:19 +0200 Arnd Bergmann <arnd@arndb.de> wrote: > > > > > > > This is another attempt to avoid a regression in wwn_to_u64() after > > > > that started using get_unaligned_be64(), which in turn ran into a > > > > bug on gcc-4.9 through 6.1. > > > > > > I'm still getting a couple screenfuls of things like > > > > > > net/tipc/name_distr.c: In function 'tipc_named_process_backlog': > > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 3 has type 'unsigned int' > > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 4 has type 'unsigned int' > > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'unsigned int' > > > net/tipc/name_distr.c:330: warning: format '%u' expects type 'unsigned int', but argument 7 has type 'unsigned int' > > > > I've built a few thousand kernels (arm32 with gcc-6.1) with the patch applied, > > but didn't see this one. What target architecture and compiler version produced > > this? Does it go away if you add a (__u32) cast? I don't even know what the > > warning is trying to tell me. > > heh, I didn't actually read it. > > Hopefully we can write this off as a gcc-4.4.4 glitch. 4.8.4 is OK. Ah, old compiler. I've tried gcc-4.3 now on ARM, and I don't get this warning (just a lot "may be used uninitialized"), but unlike gcc-4.4, my version doesn't actually get into the code path I have changed because __builtin_bswap32 was only introduced with 4.4. I don't have gcc-4.4 and 4.5 here, but the warning does show up with 4.6, 4.7 and 4.8: drivers/soc/sunxi/sunxi_sram.c: In function ‘sunxi_sram_show’: drivers/soc/sunxi/sunxi_sram.c:103:7: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘unsigned int’ [-Wformat=] 4.8 is probably still common enough that we should try to address this. This change addresses the problem for me with ARM gcc-4.8, but adding two more type casts. This also makes the 16/32/64 bit swaps all look the same. I would expect this to also have the same effect on 4.4. Please fold into the previous patch. Signed-off-by: Arnd Bergmann <arnd@arndb.de> diff --git a/include/uapi/linux/swab.h b/include/uapi/linux/swab.h index d737804af181..8f3a8f606fd9 100644 --- a/include/uapi/linux/swab.h +++ b/include/uapi/linux/swab.h @@ -97,7 +97,7 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val) * @x: value to byteswap */ #ifdef __HAVE_BUILTIN_BSWAP16__ -#define __swab16(x) __builtin_bswap16((__u16)(x)) +#define __swab16(x) (__u16)__builtin_bswap16((__u16)(x)) #else #define __swab16(x) \ (__builtin_constant_p((__u16)(x)) ? \ @@ -110,7 +110,7 @@ static inline __attribute_const__ __u32 __fswahb32(__u32 val) * @x: value to byteswap */ #ifdef __HAVE_BUILTIN_BSWAP32__ -#define __swab32(x) __builtin_bswap32((__u32)(x)) +#define __swab32(x) (__u32)__builtin_bswap32((__u32)(x)) #else #define __swab32(x) \ (__builtin_constant_p((__u32)(x)) ? \
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web