]> git.hungrycats.org Git - linux/commitdiff
[TCP]: Add tcp_tso_win_divisor sysctl.
authorDavid S. Miller <davem@nuts.davemloft.net>
Thu, 30 Sep 2004 13:09:28 +0000 (06:09 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Thu, 30 Sep 2004 13:09:28 +0000 (06:09 -0700)
This allows control over what percentage of
the congestion window can be consumed by a
single TSO frame.

The setting of this parameter is a choice
between burstiness and building larger TSO
frames.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/sysctl.h
include/net/tcp.h
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp_output.c

index e55ff44180b82eed77927fb6c839e53296374ba6..8db31f8d17ffd5036621fd324e919d801d5cf6b7 100644 (file)
@@ -341,6 +341,7 @@ enum
        NET_TCP_BIC_LOW_WINDOW=104,
        NET_TCP_DEFAULT_WIN_SCALE=105,
        NET_TCP_MODERATE_RCVBUF=106,
+       NET_TCP_TSO_WIN_DIVISOR=107,
 };
 
 enum {
index dc8decf5ff55d760b95ab1b91e15ac4a33ebd86d..90c1142ec5ebfd72c1fef0783e04abec2435260f 100644 (file)
@@ -609,6 +609,7 @@ extern int sysctl_tcp_bic;
 extern int sysctl_tcp_bic_fast_convergence;
 extern int sysctl_tcp_bic_low_window;
 extern int sysctl_tcp_moderate_rcvbuf;
+extern int sysctl_tcp_tso_win_divisor;
 
 extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
index b169ea074dc7d8617686ac75b3e2a516f5b867f9..d567f4a9f59548fa96a4d4354a5c5a74e3500d6e 100644 (file)
@@ -674,6 +674,14 @@ ctl_table ipv4_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
        },
+       {
+               .ctl_name       = NET_TCP_TSO_WIN_DIVISOR,
+               .procname       = "tcp_tso_win_divisor",
+               .data           = &sysctl_tcp_tso_win_divisor,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
        { .ctl_name = 0 }
 };
 
index 6c4873b15d91cae02f887582d1d404cc7e768c12..cd67ffb23f0d2b3a46d85bbb59837f167cf39586 100644 (file)
 /* People can turn this off for buggy TCP's found in printers etc. */
 int sysctl_tcp_retrans_collapse = 1;
 
+/* This limits the percentage of the congestion window which we
+ * will allow a single TSO frame to consume.  Building TSO frames
+ * which are too large can cause TCP streams to be bursty.
+ */
+int sysctl_tcp_tso_win_divisor = 8;
+
 static __inline__
 void update_send_head(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
 {
@@ -658,7 +664,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large)
 {
        struct tcp_opt *tp = tcp_sk(sk);
        struct dst_entry *dst = __sk_dst_get(sk);
-       int do_large, mss_now;
+       unsigned int do_large, mss_now;
 
        mss_now = tp->mss_cache_std;
        if (dst) {
@@ -673,7 +679,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large)
                    !tp->urg_mode);
 
        if (do_large) {
-               int large_mss, factor;
+               unsigned int large_mss, factor, limit;
 
                large_mss = 65535 - tp->af_specific->net_header_len -
                        tp->ext_header_len - tp->ext2_header_len -
@@ -683,13 +689,19 @@ unsigned int tcp_current_mss(struct sock *sk, int large)
                        large_mss = max((tp->max_window>>1),
                                        68U - tp->tcp_header_len);
 
+               factor = large_mss / mss_now;
+
                /* Always keep large mss multiple of real mss, but
-                * do not exceed 1/4 of the congestion window so we
-                * can keep the ACK clock ticking.
+                * do not exceed 1/tso_win_divisor of the congestion window
+                * so we can keep the ACK clock ticking and minimize
+                * bursting.
                 */
-               factor = large_mss / mss_now;
-               if (factor > (tp->snd_cwnd >> 2))
-                       factor = max(1, tp->snd_cwnd >> 2);
+               limit = tp->snd_cwnd;
+               if (sysctl_tcp_tso_win_divisor)
+                       limit /= sysctl_tcp_tso_win_divisor;
+               limit = max(1U, limit);
+               if (factor > limit)
+                       factor = limit;
 
                tp->mss_cache = mss_now * factor;