All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnd Bergmann <arnd@arndb.de>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
	Mike Frysinger <vapier@gentoo.org>,
	Paul Mundt <lethal@linux-sh.org>,
	Magnus Damm <magnus.damm@gmail.com>,
	Richard Henderson <rth@twiddle.net>
Subject: Re: [GIT PULL] asm-generic fixes
Date: Tue, 23 Jun 2009 21:56:45 +0200	[thread overview]
Message-ID: <200906232156.46865.arnd@arndb.de> (raw)
In-Reply-To: <alpine.LFD.2.01.0906231126460.3240@localhost.localdomain>

On Tuesday 23 June 2009, Linus Torvalds wrote:
> You might need to make 'result', 'carry', and 'w' be 'unsigned int' too.

Yes, you're right.

> Now, it's possible (even likely) that even with a 64-bit word, we'll never 
> actually do large enough areas that 'result' would ever have very many 
> bits set in the 32+ bit region, and since we do end up folding to 16 bits 
> twice (once after the loop and once at the end), it probably gets things 
> right in most cases. But I doubt "probably" is strong enough. Somebody 
> should check.

I think it would overrun only if we have more than 65536 u32 words of
0xffffffff in a single IP packet, on a 64 bit machine. A more obvious
reason to change it is that it relies on from32to16() actually behaving
like a from47to16() function on 64-bit. Changing it to use unsigned int
throughout makes it both more obvious and more consistent between
32 and 64 bit unsigned long types.

> Or just see arch/alpha/lib/checksum.c, which does the whole 64-bit case.
> Maybe lib/checksum.c should be lib/checksum_{32,64}.c.

Mike Frysinger earlier suggested just making the do_csum function optional
in this file because this is the one that most architectures would override.

The alpha code is the only 64-bit platform implementing do_csum in C, so
if Richard wants to use the generic code in its current form, he could simply
override the do_csum implementation.

I've now added these two patches:

commit 217a8c7b6af924379a2083439b4bb606f332e7b1
Author: Arnd Bergmann <arnd@arndb.de>
Date:   Tue Jun 23 21:37:26 2009 +0200

    lib/checksum.c: make do_csum optional
    
    Mike Frysinger suggested that do_csum should be optional
    so that an architecture can use the generic checksum code
    but still provide an optimized fast-path for the most
    critical function.
    
    This can mean an implementation using inline assembly,
    or in case of Alpha one using 64-bit arithmetic in C.
    
    Cc: Mike Frysinger <vapier@gentoo.org>
    Signed-off-by: Arnd Bergmann <arnd@arndb.de>

diff --git a/lib/checksum.c b/lib/checksum.c
index 886b48d..b08c2d0 100644
--- a/lib/checksum.c
+++ b/lib/checksum.c
@@ -37,6 +37,7 @@
 
 #include <asm/byteorder.h>
 
+#ifndef do_csum
 static inline unsigned short from32to16(unsigned int x)
 {
 	/* add up 16-bit and 16-bit for 16+c bit */
@@ -102,6 +103,7 @@ static unsigned int do_csum(const unsigned char *buff, int len)
 out:
 	return result;
 }
+#endif
 
 /*
  *	This is a version of ip_compute_csum() optimized for IP headers,

commit 5cb59758c3e2170b24e9c0d659eb6c03872155c0
Author: Arnd Bergmann <arnd@arndb.de>
Date:   Tue Jun 23 21:22:58 2009 +0200

    lib/checksum.c: use 32-bit arithmetic consistently
    
    The use of 'unsigned long' variables in the 32-bit part of do_csum()
    is confusing at best, and potentially broken for long input on 64-bit
    machines.
    
    This changes the code to use 'unsigned int' instead, which makes
    the code behave in the same (correct) way on both 32 and 64 bit
    machines.
    
    Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Arnd Bergmann <arnd@arndb.de>

diff --git a/lib/checksum.c b/lib/checksum.c
index b2e2fd4..886b48d 100644
--- a/lib/checksum.c
+++ b/lib/checksum.c
@@ -37,7 +37,7 @@
 
 #include <asm/byteorder.h>
 
-static inline unsigned short from32to16(unsigned long x)
+static inline unsigned short from32to16(unsigned int x)
 {
 	/* add up 16-bit and 16-bit for 16+c bit */
 	x = (x & 0xffff) + (x >> 16);
@@ -49,7 +49,7 @@ static inline unsigned short from32to16(unsigned long x)
 static unsigned int do_csum(const unsigned char *buff, int len)
 {
 	int odd, count;
-	unsigned long result = 0;
+	unsigned int result = 0;
 
 	if (len <= 0)
 		goto out;
@@ -73,9 +73,9 @@ static unsigned int do_csum(const unsigned char *buff, int len)
 		}
 		count >>= 1;		/* nr of 32-bit words.. */
 		if (count) {
-			unsigned long carry = 0;
+			unsigned int carry = 0;
 			do {
-				unsigned long w = *(unsigned int *) buff;
+				unsigned int w = *(unsigned int *) buff;
 				count--;
 				buff += 4;
 				result += carry;

      reply	other threads:[~2009-06-23 19:56 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-23 15:20 [GIT PULL] asm-generic fixes Arnd Bergmann
2009-06-23 18:33 ` Linus Torvalds
2009-06-23 19:56   ` Arnd Bergmann [this message]

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=200906232156.46865.arnd@arndb.de \
    --to=arnd@arndb.de \
    --cc=lethal@linux-sh.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=magnus.damm@gmail.com \
    --cc=rth@twiddle.net \
    --cc=torvalds@linux-foundation.org \
    --cc=vapier@gentoo.org \
    /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.