Module Name:    src
Committed By:   bouyer
Date:           Tue Oct 12 10:13:12 UTC 2010

Modified Files:
        src/sys/arch/mips/mips [netbsd-4]: in_cksum.c

Log Message:
Pull up following revision(s) (requested by tsutsui in ticket #1407):
        sys/arch/mips/mips/in_cksum.c: revision 1.14
Fix wrong checksum calculations of 32 bit unaligned two byte payloads.
Analyzed in PR port-mips/43882, but applied slightly different patch.
Also put some changes for readability.
Note netbsd-5 doesn't use this MD version but netbsd-4 needs a pullup.
(though it's unclear if it's really faster even on modern aggressive gcc4)


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.12.12.1 src/sys/arch/mips/mips/in_cksum.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/mips/in_cksum.c
diff -u src/sys/arch/mips/mips/in_cksum.c:1.12 src/sys/arch/mips/mips/in_cksum.c:1.12.12.1
--- src/sys/arch/mips/mips/in_cksum.c:1.12	Sat Mar 25 00:34:23 2006
+++ src/sys/arch/mips/mips/in_cksum.c	Tue Oct 12 10:13:12 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: in_cksum.c,v 1.12 2006/03/25 00:34:23 matt Exp $ */
+/* $NetBSD: in_cksum.c,v 1.12.12.1 2010/10/12 10:13:12 bouyer Exp $ */
 
 /*
  * Copyright (c) 1993 Regents of the University of California.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v 1.12 2006/03/25 00:34:23 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v 1.12.12.1 2010/10/12 10:13:12 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,11 +57,10 @@
 #include <machine/endian.h>
 
 union memptr {
-	unsigned int *i;
-	unsigned long *l;
-	unsigned long u;
-	unsigned short *s;
-	unsigned char *c;
+	uint32_t *l;
+	uintptr_t u;
+	uint16_t *s;
+	uint8_t *c;
 };
 
 static inline uint32_t fastsum(union memptr, int, unsigned int, int);
@@ -84,10 +83,6 @@
 
 	/* Align to 32 bits. */
 	if (buf.u & 0x3) {
-		/* Skip to the end for very small mbufs */
-		if (n < 3)
-			goto verylittleleft;
-
 		/*
 	         * 16-bit-align.
 		 * If buf is odd-byte-aligned, add the byte and toggle
@@ -108,6 +103,9 @@
 			n -= 1;
 			odd_aligned = !odd_aligned;
 		}
+		/* Skip to the end for very small mbufs */
+		if (n <= 2)
+			goto postunaligned;
 
 		/* 32-bit-align */
 		if (buf.u & 0x2) {
@@ -199,7 +197,7 @@
 
  notmuchleft:
 	high = hilo = 0;
-	while (n >= 4) {
+	while (n >= sizeof(uint32_t)) {
 		w0 = *(buf.l++);
 		hilo += w0;
 		high += w0 >> 16;
@@ -209,19 +207,21 @@
 	sum += hilo;
 	sum += high;
 
-	while (n > 1) {
-		n -= sizeof(*buf.s);
+ postunaligned:
+	/* handle post 32bit unaligned payloads */
+	if (n >= sizeof(uint16_t)) {
 		sum += *(buf.s++);
+		n -= sizeof(uint16_t);
 	}
 
- verylittleleft:
-	/* handle trailing byte and short (possibly) unaligned payloads */
-	while (n-- > 0) {
+	/* handle a trailing odd byte */
+	if (n > 0) {
 #if BYTE_ORDER == BIG_ENDIAN
 		sum += *(buf.c++) << 8;
 #else
 		sum += *(buf.c++);
 #endif
+		n = 0;
 	}
 
 	/*

Reply via email to