:#6  0xc02fe396 in calltrap () at /usr/src/sys/platform/pc32/i386/exception.=
:s:783
:#7  0xc0233d36 in sack_block_lookup (scb=3D0xdace6b0c, seq=3D1554912228, sb=
:=3D0xdaa45a90) at /usr/src/sys/netinet/tcp_sack.c:128
:#8  0xc0233eda in tcp_sack_nextseg (tp=3D0xdace6a20, nextrexmt=3D0xdaa45ad0=
:, plen=3D0xdaa45ad4, lostdup=3D0xdaa45acc) at /usr/src/sys/netinet/tcp_sack=
:=2Ec:496
:#9  0xc022f603 in tcp_sack_rexmt (tp=3D0xdace6a20, th=3D<value optimized ou=

    Hmm.  I see two places where a node is removed from the sackblocks list
    but lastfound is not cleared on match.  I don't know if this is the
    issue but it's the most obvious from looking at the failure.

    I'll commit this tomorrow if no new developments come up.

                                        -Matt
                                        Matthew Dillon 
                                        <[EMAIL PROTECTED]>

Index: tcp_sack.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_sack.c,v
retrieving revision 1.6
diff -u -p -r1.6 tcp_sack.c
--- tcp_sack.c  22 Apr 2007 01:13:14 -0000      1.6
+++ tcp_sack.c  3 Feb 2008 01:32:16 -0000
@@ -176,7 +176,7 @@ 
        sb = TAILQ_FIRST(&scb->sackblocks);
        while (sb && SEQ_LEQ(sb->sblk_end, th_ack)) {
                nb = TAILQ_NEXT(sb, sblk_list);
-               if (sb == scb->lastfound)
+               if (scb->lastfound == sb)
                        scb->lastfound = NULL;
                TAILQ_REMOVE(&scb->sackblocks, sb, sblk_list);
                free_sackblock(sb);
@@ -334,6 +334,8 @@         SEQ_GEQ(workingblock->sblk_end, sb-
                struct sackblock *nextblock;
 
                nextblock = TAILQ_NEXT(sb, sblk_list);
+               if (scb->lastfound == sb)
+                       scb->lastfound = NULL;
                /* Remove completely overlapped block */
                TAILQ_REMOVE(&scb->sackblocks, sb, sblk_list);
                free_sackblock(sb);
@@ -346,6 +348,8 @@     if (sb != NULL &&
            SEQ_GEQ(workingblock->sblk_end, sb->sblk_start)) {
                /* Extend new block to cover partially overlapped old block. */
                workingblock->sblk_end = sb->sblk_end;
+               if (scb->lastfound == sb)
+                       scb->lastfound = NULL;
                TAILQ_REMOVE(&scb->sackblocks, sb, sblk_list);
                free_sackblock(sb);
                --scb->nblocks;

Reply via email to