svn commit: r197854 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/xen/xenpci netinet

Robert Watson rwatson at FreeBSD.org
Thu Oct 8 11:07:16 UTC 2009


Author: rwatson
Date: Thu Oct  8 11:07:15 2009
New Revision: 197854
URL: http://svn.freebsd.org/changeset/base/197854

Log:
  Merge r197795 from head to stable/8:
  
    In tcp_input(), we acquire a global write lock at first only if a
    segment is likely to trigger a TCP state change (i.e., FIN/RST/SYN).
    If we later have to upgrade the lock, we acquire an inpcb reference
    and drop both global/inpcb locks before reacquiring in-order.  In
    that gap, the connection may transition into TIMEWAIT, so we need
    to loop back and reevaluate the inpcb after relocking.
  
    Reported by:        Kamigishi Rei <spambox at haruhiism.net>
    Reviewed by:        bz
  
  Approved by:	re (kib)

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/netinet/tcp_input.c

Modified: stable/8/sys/netinet/tcp_input.c
==============================================================================
--- stable/8/sys/netinet/tcp_input.c	Thu Oct  8 10:26:49 2009	(r197853)
+++ stable/8/sys/netinet/tcp_input.c	Thu Oct  8 11:07:15 2009	(r197854)
@@ -648,6 +648,7 @@ findpcb:
 	 * tried to free the inpcb, in which case we need to loop back and
 	 * try to find a new inpcb to deliver to.
 	 */
+relocked:
 	if (inp->inp_flags & INP_TIMEWAIT) {
 		KASSERT(ti_locked == TI_RLOCKED || ti_locked == TI_WLOCKED,
 		    ("%s: INP_TIMEWAIT ti_locked %d", __func__, ti_locked));
@@ -698,7 +699,8 @@ findpcb:
 	 * We've identified a valid inpcb, but it could be that we need an
 	 * inpcbinfo write lock and have only a read lock.  In this case,
 	 * attempt to upgrade/relock using the same strategy as the TIMEWAIT
-	 * case above.
+	 * case above.  If we relock, we have to jump back to 'relocked' as
+	 * the connection might now be in TIMEWAIT.
 	 */
 	if (tp->t_state != TCPS_ESTABLISHED ||
 	    (thflags & (TH_SYN | TH_FIN | TH_RST)) != 0 ||
@@ -720,6 +722,7 @@ findpcb:
 					goto findpcb;
 				}
 				tcp_wlock_relocked++;
+				goto relocked;
 			} else {
 				ti_locked = TI_WLOCKED;
 				tcp_wlock_upgraded++;


More information about the svn-src-all mailing list