All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: Russell King <linux@armlinux.org.uk>
Cc: Arnd Bergmann <arnd@arndb.de>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH] ARM: make memzero optimization smarter
Date: Tue,  5 Sep 2017 17:05:37 +0200	[thread overview]
Message-ID: <20170905150559.1739140-1-arnd@arndb.de> (raw)

While testing with a gcc-8.0.0 snapshot, I ran into a harmless
build warning:

In file included from include/linux/string.h:18:0,
		 ...
                 from drivers/net/ethernet/hisilicon/hns/hns_ethtool.c:10:
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c: In function '__lb_other_process':
arch/arm/include/asm/string.h:50:5: error: 'memset' specified size 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
     memset((__p),(v),(__n));  \
     ^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c:394:3: note: in expansion of macro 'memset'
   memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
   ^~~~~~

I think the warning is unintentional here, and gcc should not actually
warn, so I reported this in the gcc bugzilla as pr82103.

The problem here is that testing the 'frame_size' variable for non-zero
in the first memset() macro invocation leads to a code path in which
gcc thinks it may be zero, and that code path would lead to an overly
large length for the following memset that is now "(u32)-1". We know
this won't happen as the skb len is already guaranteed to be nonzero
when we get here (it has just been allocated with a nonzero size).

However, we can avoid this class of bogus warnings for the memset() macro
by only doing the micro-optimization for zero-length arguments when the
length is a compile-time constant. This should also reduce code size by
a few bytes, and avoid an extra branch for the cases that a variable-length
argument is always nonzero, which is probably the common case anyway.

I have made sure that the __memzero implementation can safely handle
a zero length argument.

Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82103
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/include/asm/string.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
index fe1c6af3a1b1..d4f464b46eae 100644
--- a/arch/arm/include/asm/string.h
+++ b/arch/arm/include/asm/string.h
@@ -43,7 +43,7 @@ extern void __memzero(void *ptr, __kernel_size_t n);
 #define memset(p,v,n)							\
 	({								\
 	 	void *__p = (p); size_t __n = n;			\
-		if ((__n) != 0) {					\
+		if (!__builtin_constant_p(__n) || (__n) != 0) {		\
 			if (__builtin_constant_p((v)) && (v) == 0)	\
 				__memzero((__p),(__n));			\
 			else						\
-- 
2.9.0

WARNING: multiple messages have this Message-ID (diff)
From: arnd@arndb.de (Arnd Bergmann)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: make memzero optimization smarter
Date: Tue,  5 Sep 2017 17:05:37 +0200	[thread overview]
Message-ID: <20170905150559.1739140-1-arnd@arndb.de> (raw)

While testing with a gcc-8.0.0 snapshot, I ran into a harmless
build warning:

In file included from include/linux/string.h:18:0,
		 ...
                 from drivers/net/ethernet/hisilicon/hns/hns_ethtool.c:10:
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c: In function '__lb_other_process':
arch/arm/include/asm/string.h:50:5: error: 'memset' specified size 4294967295 exceeds maximum object size 2147483647 [-Werror=stringop-overflow=]
     memset((__p),(v),(__n));  \
     ^~~~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/hisilicon/hns/hns_ethtool.c:394:3: note: in expansion of macro 'memset'
   memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
   ^~~~~~

I think the warning is unintentional here, and gcc should not actually
warn, so I reported this in the gcc bugzilla as pr82103.

The problem here is that testing the 'frame_size' variable for non-zero
in the first memset() macro invocation leads to a code path in which
gcc thinks it may be zero, and that code path would lead to an overly
large length for the following memset that is now "(u32)-1". We know
this won't happen as the skb len is already guaranteed to be nonzero
when we get here (it has just been allocated with a nonzero size).

However, we can avoid this class of bogus warnings for the memset() macro
by only doing the micro-optimization for zero-length arguments when the
length is a compile-time constant. This should also reduce code size by
a few bytes, and avoid an extra branch for the cases that a variable-length
argument is always nonzero, which is probably the common case anyway.

I have made sure that the __memzero implementation can safely handle
a zero length argument.

Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82103
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm/include/asm/string.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
index fe1c6af3a1b1..d4f464b46eae 100644
--- a/arch/arm/include/asm/string.h
+++ b/arch/arm/include/asm/string.h
@@ -43,7 +43,7 @@ extern void __memzero(void *ptr, __kernel_size_t n);
 #define memset(p,v,n)							\
 	({								\
 	 	void *__p = (p); size_t __n = n;			\
-		if ((__n) != 0) {					\
+		if (!__builtin_constant_p(__n) || (__n) != 0) {		\
 			if (__builtin_constant_p((v)) && (v) == 0)	\
 				__memzero((__p),(__n));			\
 			else						\
-- 
2.9.0

             reply	other threads:[~2017-09-05 15:06 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-05 15:05 Arnd Bergmann [this message]
2017-09-05 15:05 ` [PATCH] ARM: make memzero optimization smarter Arnd Bergmann
2018-01-16 16:28 Arnd Bergmann
2018-01-16 17:10 ` Nicolas Pitre
2018-01-16 22:30   ` Arnd Bergmann
2018-01-17  4:07     ` Nicolas Pitre
2018-01-17  4:07       ` Nicolas Pitre
2018-01-17 10:58       ` Russell King - ARM Linux
2018-01-17 10:58         ` Russell King - ARM Linux
2018-01-17 14:03         ` Nicolas Pitre
2018-01-17 14:03           ` Nicolas Pitre
2018-01-17 21:14           ` Nicolas Pitre
2018-01-17 21:14             ` Nicolas Pitre

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170905150559.1739140-1-arnd@arndb.de \
    --to=arnd@arndb.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.