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;
}
/*