Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 23 Jun 2016 08:38:01 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r302132 - stable/10/sys/netinet
Message-ID:  <201606230838.u5N8c1w8054458@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Thu Jun 23 08:38:01 2016
New Revision: 302132
URL: https://svnweb.freebsd.org/changeset/base/302132

Log:
  MFC 300981
  
      tcp: Don't prematurely drop receiving-only connections
  
      If the connection was persistent and receiving-only, several (12)
      sporadic device insufficient buffers would cause the connection be
      dropped prematurely:
      Upon ENOBUFS in tcp_output() for an ACK, retransmission timer is
      started.  No one will stop this retransmission timer for receiving-
      only connection, so the retransmission timer promises to expire and
      t_rxtshift is promised to be increased.  And t_rxtshift will not be
      reset to 0, since no RTT measurement will be done for receiving-only
      connection.  If this receiving-only connection lived long enough
      (e.g. >350sec, given the RTO starts from 200ms), and it suffered 12
      sporadic device insufficient buffers, i.e. t_rxtshift >= 12, this
      receiving-only connection would be dropped prematurely by the
      retransmission timer.
  
      We now assert that for data segments, SYNs or FINs either rexmit or
      persist timer was wired upon ENOBUFS.  And don't set rexmit timer
      for other cases, i.e. ENOBUFS upon ACKs.
  
      Discussed with:     lstewart, hiren, jtl, Mike Karels
      MFC after:  3 weeks
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5872

Modified:
  stable/10/sys/netinet/tcp_output.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/netinet/tcp_output.c
==============================================================================
--- stable/10/sys/netinet/tcp_output.c	Thu Jun 23 08:28:13 2016	(r302131)
+++ stable/10/sys/netinet/tcp_output.c	Thu Jun 23 08:38:01 2016	(r302132)
@@ -127,6 +127,16 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO,
 	&VNET_NAME(tcp_autosndbuf_max), 0,
 	"Max size of automatic send buffer");
 
+/*
+ * Make sure that either retransmit or persist timer is set for SYN, FIN and
+ * non-ACK.
+ */
+#define TCP_XMIT_TIMER_ASSERT(tp, len, th_flags)			\
+	KASSERT(((len) == 0 && ((th_flags) & (TH_SYN | TH_FIN)) == 0) ||\
+	    tcp_timer_active((tp), TT_REXMT) ||				\
+	    tcp_timer_active((tp), TT_PERSIST),				\
+	    ("neither rexmt nor persist timer is set"))
+
 static void inline	hhook_run_tcp_est_out(struct tcpcb *tp,
 			    struct tcphdr *th, struct tcpopt *to,
 			    long len, int tso);
@@ -1531,9 +1541,7 @@ timer:
 			tp->t_softerror = error;
 			return (error);
 		case ENOBUFS:
-	                if (!tcp_timer_active(tp, TT_REXMT) &&
-			    !tcp_timer_active(tp, TT_PERSIST))
-	                        tcp_timer_activate(tp, TT_REXMT, tp->t_rxtcur);
+			TCP_XMIT_TIMER_ASSERT(tp, len, flags);
 			tp->snd_cwnd = tp->t_maxseg;
 			return (0);
 		case EMSGSIZE:



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