Date: Fri, 27 Aug 2010 10:16:32 +0000 (UTC) From: Andre Oppermann <andre@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r211871 - stable/7/sys/netinet Message-ID: <201008271016.o7RAGWgV074600@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: andre Date: Fri Aug 27 10:16:32 2010 New Revision: 211871 URL: http://svn.freebsd.org/changeset/base/211871 Log: MFC r211464: If a TCP connection has been idle for one retransmit timeout or more it must reset its congestion window back to the initial window. RFC3390 has increased the initial window from 1 segment to up to 4 segments. The initial window increase of RFC3390 wasn't reflected into the restart window which remained at its original defaults of 4 segments for local and 1 segment for all other connections. Both values are controllable through sysctl net.inet.tcp.local_slowstart_flightsize and net.inet.tcp.slowstart_flightsize. The increase helps TCP's slow start algorithm to open up the congestion window much faster. Reviewed by: lstewart MFC after: 1 week Modified: stable/7/sys/netinet/tcp_input.c stable/7/sys/netinet/tcp_output.c stable/7/sys/netinet/tcp_var.h Directory Properties: stable/7/sys/ (props changed) stable/7/sys/cddl/contrib/opensolaris/ (props changed) stable/7/sys/contrib/dev/acpica/ (props changed) stable/7/sys/contrib/pf/ (props changed) Modified: stable/7/sys/netinet/tcp_input.c ============================================================================== --- stable/7/sys/netinet/tcp_input.c Fri Aug 27 10:15:45 2010 (r211870) +++ stable/7/sys/netinet/tcp_input.c Fri Aug 27 10:16:32 2010 (r211871) @@ -123,7 +123,7 @@ static int tcp_do_rfc3042 = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3042, CTLFLAG_RW, &tcp_do_rfc3042, 0, "Enable RFC 3042 (Limited Transmit)"); -static int tcp_do_rfc3390 = 1; +int tcp_do_rfc3390 = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3390, CTLFLAG_RW, &tcp_do_rfc3390, 0, "Enable RFC 3390 (Increasing TCP's Initial Congestion Window)"); Modified: stable/7/sys/netinet/tcp_output.c ============================================================================== --- stable/7/sys/netinet/tcp_output.c Fri Aug 27 10:15:45 2010 (r211870) +++ stable/7/sys/netinet/tcp_output.c Fri Aug 27 10:16:32 2010 (r211871) @@ -127,7 +127,7 @@ tcp_output(struct tcpcb *tp) { struct socket *so = tp->t_inpcb->inp_socket; long len, recwin, sendwin; - int off, flags, error; + int off, flags, error, rw; struct mbuf *m; struct ip *ip = NULL; struct ipovly *ipov = NULL; @@ -163,23 +163,34 @@ tcp_output(struct tcpcb *tp) idle = (tp->t_flags & TF_LASTIDLE) || (tp->snd_max == tp->snd_una); if (idle && (ticks - (int)tp->t_rcvtime) >= tp->t_rxtcur) { /* - * We have been idle for "a while" and no acks are - * expected to clock out any data we send -- - * slow start to get ack "clock" running again. + * If we've been idle for more than one retransmit + * timeout the old congestion window is no longer + * current and we have to reduce it to the restart + * window before we can transmit again. * - * Set the slow-start flight size depending on whether - * this is a local network or not. + * The restart window is the initial window or the last + * CWND, whichever is smaller. + * + * This is done to prevent us from flooding the path with + * a full CWND at wirespeed, overloading router and switch + * buffers along the way. + * + * See RFC5681 Section 4.1. "Restarting Idle Connections". */ - int ss = ss_fltsz; + if (tcp_do_rfc3390) + rw = min(4 * tp->t_maxseg, + max(2 * tp->t_maxseg, 4380)); #ifdef INET6 - if (isipv6) { - if (in6_localaddr(&tp->t_inpcb->in6p_faddr)) - ss = ss_fltsz_local; - } else -#endif /* INET6 */ - if (in_localaddr(tp->t_inpcb->inp_faddr)) - ss = ss_fltsz_local; - tp->snd_cwnd = tp->t_maxseg * ss; + else if ((isipv6 ? in6_localaddr(&tp->t_inpcb->in6p_faddr) : + in_localaddr(tp->t_inpcb->inp_faddr))) +#else + else if (in_localaddr(tp->t_inpcb->inp_faddr)) +#endif + rw = ss_fltsz_local * tp->t_maxseg; + else + rw = ss_fltsz * tp->t_maxseg; + + tp->snd_cwnd = min(rw, tp->snd_cwnd); } tp->t_flags &= ~TF_LASTIDLE; if (idle) { Modified: stable/7/sys/netinet/tcp_var.h ============================================================================== --- stable/7/sys/netinet/tcp_var.h Fri Aug 27 10:15:45 2010 (r211870) +++ stable/7/sys/netinet/tcp_var.h Fri Aug 27 10:16:32 2010 (r211871) @@ -513,6 +513,7 @@ extern int tcp_mssdflt; /* XXX */ extern int tcp_minmss; extern int tcp_delack_enabled; extern int tcp_do_newreno; +extern int tcp_do_rfc3390; extern int path_mtu_discovery; extern int ss_fltsz; extern int ss_fltsz_local;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008271016.o7RAGWgV074600>