Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2009 22:24:14 +0000 (UTC)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r197795 - head/sys/netinet
Message-ID:  <200910052224.n95MOEXH027549@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rwatson
Date: Mon Oct  5 22:24:13 2009
New Revision: 197795
URL: http://svn.freebsd.org/changeset/base/197795

Log:
  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.
  
  MFC after:	3 days
  Reported by:	Kamigishi Rei <spambox at haruhiism.net>
  Reviewed by:	bz

Modified:
  head/sys/netinet/tcp_input.c

Modified: head/sys/netinet/tcp_input.c
==============================================================================
--- head/sys/netinet/tcp_input.c	Mon Oct  5 22:23:12 2009	(r197794)
+++ head/sys/netinet/tcp_input.c	Mon Oct  5 22:24:13 2009	(r197795)
@@ -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++;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910052224.n95MOEXH027549>