Index: netinet/tcp_output.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_output.c,v retrieving revision 1.112 diff -u -p -r1.112 tcp_output.c --- netinet/tcp_output.c 21 May 2005 00:38:29 -0000 1.112 +++ netinet/tcp_output.c 17 Nov 2006 13:57:33 -0000 @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -104,6 +105,18 @@ int tcp_do_newreno = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, newreno, CTLFLAG_RW, &tcp_do_newreno, 0, "Enable NewReno Algorithms"); +int tcp_do_autosndbuf = 1; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, sndbuf_auto, CTLFLAG_RW, + &tcp_do_autosndbuf, 0, "Enable automatic send buffers"); + +int tcp_autosndbuf_inc = 8*1024; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, sndbuf_inc, CTLFLAG_RW, + &tcp_autosndbuf_inc, 0, "Incrementor step size of automatic send buffer"); + +int tcp_autosndbuf_max = 256*1024; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, sndbuf_max, CTLFLAG_RW, + &tcp_autosndbuf_max, 0, "Max size of automatic send buffer"); + /* * Tcp output routine: figure out what should be sent and send it. */ @@ -372,8 +385,56 @@ after_sack_rexmit: } } + /* len will be >= 0 after this point. */ + KASSERT(len >= 0, ("%s: len < 0", __func__)); + + /* + * Automatic sizing of send socket buffer. Often the send buffer + * size is not optimally adjusted to the actual network conditions + * at hand (delay bandwidth product). Setting the buffer size too + * small limits throughput on links with high bandwidth and high + * delay (eg. trans-continental/oceanic links). Setting the + * buffer size too big consumes too much real kernel memory, + * especially with many connections on busy servers. + * + * The criteria to step up the send buffer one notch are: + * 1. receive window of remote host is larger than send buffer + * (with a fudge factor of 5/4th); + * 2. send buffer is filled to 7/8th with data (so we actually + * have data to make use of it); + * 3. send buffer fill has not hit maximal automatic size; + * 4. our send window (slow start and cogestion controlled) is + * larger than sent but unacknowledged data in send buffer. + * + * The remote host receive window scaling factor may limit the + * growing of the send buffer before it reaches its allowed + * maximum. + * + * Optional: Shrink send buffer during idle periods together + * with congestion window. Requires another timer. Has to + * wait for upcoming tcp timer rewrite. + */ + if (tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) { + if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat && + so->so_snd.sb_cc >= (so->so_snd.sb_hiwat / 8 * 7) && + so->so_snd.sb_cc < tcp_autosndbuf_max && + sendwin >= (so->so_snd.sb_cc - (tp->snd_nxt - tp->snd_una))) { +#if 1 + log(LOG_DEBUG, "%s: inc sockbuf, old %i, new %i, " + "sb_cc %i, snd_wnd %i, sendwnd %i\n", + __func__, so->so_snd.sb_hiwat, + so->so_snd.sb_hiwat + tcp_autosndbuf_inc, + so->so_snd.sb_cc, (int)tp->snd_wnd, (int)sendwin); +#endif + (void)sbreserve_locked(&so->so_snd, + min(so->so_snd.sb_hiwat + tcp_autosndbuf_inc, + tcp_autosndbuf_max), + so, curthread); + } + } + /* - * len will be >= 0 after this point. Truncate to the maximum + * Truncate to the maximum * segment length and ensure that FIN is removed if the length * no longer contains the last data byte. */ Index: netinet/tcp_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.124.2.3 diff -u -p -r1.124.2.3 tcp_usrreq.c --- netinet/tcp_usrreq.c 27 Sep 2006 09:24:44 -0000 1.124.2.3 +++ netinet/tcp_usrreq.c 17 Nov 2006 13:57:33 -0000 @@ -1191,6 +1191,8 @@ tcp_attach(so) if (error) return (error); } + so->so_rcv.sb_flags |= SB_AUTOSIZE; + so->so_snd.sb_flags |= SB_AUTOSIZE; error = in_pcballoc(so, &tcbinfo, "tcpinp"); if (error) return (error); Index: sys/socketvar.h =================================================================== RCS file: /home/ncvs/src/sys/sys/socketvar.h,v retrieving revision 1.141.2.1 diff -u -p -r1.141.2.1 socketvar.h --- sys/socketvar.h 28 Jun 2006 14:33:47 -0000 1.141.2.1 +++ sys/socketvar.h 17 Nov 2006 13:57:33 -0000 @@ -128,6 +128,7 @@ struct socket { #define SB_NOINTR 0x40 /* operations not interruptible */ #define SB_AIO 0x80 /* AIO operations queued */ #define SB_KNOTE 0x100 /* kernel note attached */ +#define SB_AUTOSIZE 0x800 /* automatically size socket buffer */ void (*so_upcall)(struct socket *, void *, int); void *so_upcallarg;