linux-mips
[Top] [All Lists]

Re: MIPS checksum bug

To: Bryan Phillippe <u1@terran.org>
Subject: Re: MIPS checksum bug
From: "Maciej W. Rozycki" <macro@linux-mips.org>
Date: Wed, 17 Sep 2008 11:40:01 +0100 (BST)
Cc: linux-mips@linux-mips.org
In-reply-to: <B45397E7-EBE4-497B-9055-42B604A909AA@terran.org>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <072748C6-07A9-4167-A8A5-80D0F7D9C784@darkforest.org> <B45397E7-EBE4-497B-9055-42B604A909AA@terran.org>
Sender: linux-mips-bounce@linux-mips.org
On Tue, 16 Sep 2008, Bryan Phillippe wrote:

> 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?

 It seems obvious that a carry from the bit #15 in the last addition of
the passed checksum -- ADDC(sum, a2) -- will negate the effect of the
folding.  However a simpler fix should do as well.  Try if the following
patch works for you.  Please note this is completely untested and further
optimisation is possible, but I've skipped it in this version for clarity.

 Thanks for raising the issue.

  Maciej

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
--- a/arch/mips/lib/csum_partial.S      2008-05-05 02:55:23.000000000 
+0000
+++ b/arch/mips/lib/csum_partial.S      2008-09-17 10:32:37.000000000 
+0000
@@ -253,6 +253,9 @@ LEAF(csum_partial)
 
 1:     ADDC(sum, t1)
 
+       /* Add the passed partial csum.  */
+       ADDC(sum, a2)
+
        /* fold checksum */
        .set    push
        .set    noat
@@ -278,11 +281,8 @@ LEAF(csum_partial)
        andi    sum, 0xffff
        .set    pop
 1:
-       .set    reorder
-       /* Add the passed partial csum.  */
-       ADDC(sum, a2)
        jr      ra
-       .set    noreorder
+        nop
        END(csum_partial)
 
 

<Prev in Thread] Current Thread [Next in Thread>