MIPS checksum bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

It appears that the following problem once reported for Sparc64 affects MIPS/64 as well:

original report: http://www.spinics.net/lists/sparclinux/msg00173.html
resolution: http://www.spinics.net/lists/sparclinux/msg00179.html

The net result is that when TCP fragments unacked segments due to PMTU discovery, the shortened segment can have a bad TCP csum. I'm testing on Linux-2.6.26 (FWIW, on a Cavium CN3010). My repro is fairly simple: MIPS/64 client behind a Linux router, where the Linux router has an outbound MTU of 1492. When the client attempts to send segments of size 1460 (1500), the router sends back an ICMP unreachable/PMTU and the client resends the first portion of the segment reduced to 1452 (1492), and the segments *often* (but not always) have a bad TCP csum. Note that you can't have hardware checksums enabled or the bug is masked.

I've experimented with the following change:

--- /home/bp/tmp/csum_partial.S.orig	2008-09-16 12:01:00.000000000 -0700
+++ arch/mips/lib/csum_partial.S	2008-09-16 11:51:44.000000000 -0700
@@ -281,6 +281,23 @@
	.set	reorder
	/* Add the passed partial csum.  */
	ADDC(sum, a2)
+
+	/* fold checksum again to clear the high bits before returning */
+	.set	push
+	.set	noat
+#ifdef USE_DOUBLE
+	dsll32	v1, sum, 0
+	daddu	sum, v1
+	sltu	v1, sum, v1
+	dsra32	sum, sum, 0
+	addu	sum, v1
+#endif
+	sll	v1, sum, 16
+	addu	sum, v1
+	sltu	v1, sum, v1
+	srl	sum, sum, 16
+	addu	sum, v1
+
	jr	ra
	.set	noreorder
	END(csum_partial)

and it seems to fix the problem for me.  Can you comment?

Thanks,
--
-bp



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux