Author: trociny
Date: Sat Sep  1 10:32:40 2012
New Revision: 239982
URL: http://svn.freebsd.org/changeset/base/239982

Log:
  MFC r239075:
  
  In tcp timers, check INP_DROPPED flag a little later, after
  callout_deactivate(), so if INP_DROPPED is set we return with the
  timer active flag cleared.
  
  For me this fixes negative keep timer values reported by `netstat -x'
  for connections in CLOSE state.

Modified:
  stable/9/sys/netinet/tcp_timer.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/netinet/tcp_timer.c
==============================================================================
--- stable/9/sys/netinet/tcp_timer.c    Sat Sep  1 10:28:20 2012        
(r239981)
+++ stable/9/sys/netinet/tcp_timer.c    Sat Sep  1 10:32:40 2012        
(r239982)
@@ -183,13 +183,18 @@ tcp_timer_delack(void *xtp)
                return;
        }
        INP_WLOCK(inp);
-       if ((inp->inp_flags & INP_DROPPED) || 
callout_pending(&tp->t_timers->tt_delack)
-           || !callout_active(&tp->t_timers->tt_delack)) {
+       if (callout_pending(&tp->t_timers->tt_delack) ||
+           !callout_active(&tp->t_timers->tt_delack)) {
                INP_WUNLOCK(inp);
                CURVNET_RESTORE();
                return;
        }
        callout_deactivate(&tp->t_timers->tt_delack);
+       if ((inp->inp_flags & INP_DROPPED) != 0) {
+               INP_WUNLOCK(inp);
+               CURVNET_RESTORE();
+               return;
+       }
 
        tp->t_flags |= TF_ACKNOW;
        TCPSTAT_INC(tcps_delack);
@@ -229,7 +234,7 @@ tcp_timer_2msl(void *xtp)
        }
        INP_WLOCK(inp);
        tcp_free_sackholes(tp);
-       if ((inp->inp_flags & INP_DROPPED) || 
callout_pending(&tp->t_timers->tt_2msl) ||
+       if (callout_pending(&tp->t_timers->tt_2msl) ||
            !callout_active(&tp->t_timers->tt_2msl)) {
                INP_WUNLOCK(tp->t_inpcb);
                INP_INFO_WUNLOCK(&V_tcbinfo);
@@ -237,6 +242,12 @@ tcp_timer_2msl(void *xtp)
                return;
        }
        callout_deactivate(&tp->t_timers->tt_2msl);
+       if ((inp->inp_flags & INP_DROPPED) != 0) {
+               INP_WUNLOCK(inp);
+               INP_INFO_WUNLOCK(&V_tcbinfo);
+               CURVNET_RESTORE();
+               return;
+       }
        /*
         * 2 MSL timeout in shutdown went off.  If we're closed but
         * still waiting for peer to close and connection has been idle
@@ -300,14 +311,20 @@ tcp_timer_keep(void *xtp)
                return;
        }
        INP_WLOCK(inp);
-       if ((inp->inp_flags & INP_DROPPED) || 
callout_pending(&tp->t_timers->tt_keep)
-           || !callout_active(&tp->t_timers->tt_keep)) {
+       if (callout_pending(&tp->t_timers->tt_keep) ||
+           !callout_active(&tp->t_timers->tt_keep)) {
                INP_WUNLOCK(inp);
                INP_INFO_WUNLOCK(&V_tcbinfo);
                CURVNET_RESTORE();
                return;
        }
        callout_deactivate(&tp->t_timers->tt_keep);
+       if ((inp->inp_flags & INP_DROPPED) != 0) {
+               INP_WUNLOCK(inp);
+               INP_INFO_WUNLOCK(&V_tcbinfo);
+               CURVNET_RESTORE();
+               return;
+       }
        /*
         * Keep-alive timer went off; send something
         * or drop connection if idle for too long.
@@ -397,14 +414,20 @@ tcp_timer_persist(void *xtp)
                return;
        }
        INP_WLOCK(inp);
-       if ((inp->inp_flags & INP_DROPPED) || 
callout_pending(&tp->t_timers->tt_persist)
-           || !callout_active(&tp->t_timers->tt_persist)) {
+       if (callout_pending(&tp->t_timers->tt_persist) ||
+           !callout_active(&tp->t_timers->tt_persist)) {
                INP_WUNLOCK(inp);
                INP_INFO_WUNLOCK(&V_tcbinfo);
                CURVNET_RESTORE();
                return;
        }
        callout_deactivate(&tp->t_timers->tt_persist);
+       if ((inp->inp_flags & INP_DROPPED) != 0) {
+               INP_WUNLOCK(inp);
+               INP_INFO_WUNLOCK(&V_tcbinfo);
+               CURVNET_RESTORE();
+               return;
+       }
        /*
         * Persistance timer into zero window.
         * Force a byte to be output, if possible.
@@ -469,14 +492,20 @@ tcp_timer_rexmt(void * xtp)
                return;
        }
        INP_WLOCK(inp);
-       if ((inp->inp_flags & INP_DROPPED) || 
callout_pending(&tp->t_timers->tt_rexmt)
-           || !callout_active(&tp->t_timers->tt_rexmt)) {
+       if (callout_pending(&tp->t_timers->tt_rexmt) ||
+           !callout_active(&tp->t_timers->tt_rexmt)) {
                INP_WUNLOCK(inp);
                INP_INFO_RUNLOCK(&V_tcbinfo);
                CURVNET_RESTORE();
                return;
        }
        callout_deactivate(&tp->t_timers->tt_rexmt);
+       if ((inp->inp_flags & INP_DROPPED) != 0) {
+               INP_WUNLOCK(inp);
+               INP_INFO_RUNLOCK(&V_tcbinfo);
+               CURVNET_RESTORE();
+               return;
+       }
        tcp_free_sackholes(tp);
        /*
         * Retransmission timer went off.  Message has not
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to