Subject: Re: Very slow pipe/TCP connection in 1.6_BETA4
To: None <current-users@netbsd.org>
From: Charles Hannum <abuse@spamalicious.com>
List: current-users
Date: 07/16/2002 17:50:31
There is at least one problem that will cause slow performance, mostly
for loopback traffic.  Since the loopback MTU is so large (at least
32k), it's possible for the stack to send one huge packet containing
the entire send buffer (which is 16k by default), and then stall
waiting for an ack.  This is similar to the original problem that
prompted the `ack-on-push' behavior some 7+ years ago.

One way to solve it is with a patch like the following.  Note that I
have NOT tested this -- but if someone would like to do so and report
their results, that might be useful.


Index: tcp_output.c
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/tcp_output.c,v
retrieving revision 1.83
diff -u -r1.83 tcp_output.c
--- tcp_output.c	2002/06/13 16:31:05	1.83
+++ tcp_output.c	2002/07/16 17:38:57
@@ -230,6 +230,7 @@
 #ifdef INET6
 	struct in6pcb *in6p = tp->t_in6pcb;
 #endif
+	struct socket *so;
 	struct rtentry *rt;
 	struct ifnet *ifp;
 	int size;
@@ -258,12 +259,16 @@
 
 	rt = NULL;
 #ifdef INET
-	if (inp)
+	if (inp) {
 		rt = in_pcbrtentry(inp);
+		so = inp->inp_socket;
+	}
 #endif
 #ifdef INET6
-	if (in6p)
+	if (in6p) {
 		rt = in6_pcbrtentry(in6p);
+		so = in6p->in6p_socket;
+	}
 #endif
 	if (rt == NULL) {
 		size = tcp_mssdflt;
@@ -350,6 +355,14 @@
 	 * I'm not quite sure about this (could someone comment).
 	 */
 	*txsegsizep = min(tp->t_peermss - optlen, size);
+	/*
+	 * Never send more than half a buffer full.  This insures that we can
+	 * always keep 2 packets on the wire, no matter what SO_SNDBUF is, and
+	 * therefore acks will never be delayed unless we run out of data to
+	 * transmit.
+	 */
+	if (so)
+		*txsegsizep = min(so->so_snd.sb_hiwat >> 1, *txsegsizep);
 	*rxsegsizep = min(tp->t_ourmss - optlen, size);
 
 	if (*txsegsizep != tp->t_segsz) {