Commit 008f4d3c authored by David S. Miller's avatar David S. Miller

[TCP]: Add tcp_tso_win_divisor sysctl.

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: default avatarDavid S. Miller <davem@davemloft.net>
parent c2226916
...@@ -341,6 +341,7 @@ enum ...@@ -341,6 +341,7 @@ enum
NET_TCP_BIC_LOW_WINDOW=104, NET_TCP_BIC_LOW_WINDOW=104,
NET_TCP_DEFAULT_WIN_SCALE=105, NET_TCP_DEFAULT_WIN_SCALE=105,
NET_TCP_MODERATE_RCVBUF=106, NET_TCP_MODERATE_RCVBUF=106,
NET_TCP_TSO_WIN_DIVISOR=107,
}; };
enum { enum {
......
...@@ -609,6 +609,7 @@ extern int sysctl_tcp_bic; ...@@ -609,6 +609,7 @@ extern int sysctl_tcp_bic;
extern int sysctl_tcp_bic_fast_convergence; extern int sysctl_tcp_bic_fast_convergence;
extern int sysctl_tcp_bic_low_window; extern int sysctl_tcp_bic_low_window;
extern int sysctl_tcp_moderate_rcvbuf; extern int sysctl_tcp_moderate_rcvbuf;
extern int sysctl_tcp_tso_win_divisor;
extern atomic_t tcp_memory_allocated; extern atomic_t tcp_memory_allocated;
extern atomic_t tcp_sockets_allocated; extern atomic_t tcp_sockets_allocated;
......
...@@ -674,6 +674,14 @@ ctl_table ipv4_table[] = { ...@@ -674,6 +674,14 @@ ctl_table ipv4_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec, .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 } { .ctl_name = 0 }
}; };
......
...@@ -45,6 +45,12 @@ ...@@ -45,6 +45,12 @@
/* People can turn this off for buggy TCP's found in printers etc. */ /* People can turn this off for buggy TCP's found in printers etc. */
int sysctl_tcp_retrans_collapse = 1; 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__ static __inline__
void update_send_head(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb) 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) ...@@ -658,7 +664,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large)
{ {
struct tcp_opt *tp = tcp_sk(sk); struct tcp_opt *tp = tcp_sk(sk);
struct dst_entry *dst = __sk_dst_get(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; mss_now = tp->mss_cache_std;
if (dst) { if (dst) {
...@@ -673,7 +679,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large) ...@@ -673,7 +679,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large)
!tp->urg_mode); !tp->urg_mode);
if (do_large) { if (do_large) {
int large_mss, factor; unsigned int large_mss, factor, limit;
large_mss = 65535 - tp->af_specific->net_header_len - large_mss = 65535 - tp->af_specific->net_header_len -
tp->ext_header_len - tp->ext2_header_len - tp->ext_header_len - tp->ext2_header_len -
...@@ -683,13 +689,19 @@ unsigned int tcp_current_mss(struct sock *sk, int large) ...@@ -683,13 +689,19 @@ unsigned int tcp_current_mss(struct sock *sk, int large)
large_mss = max((tp->max_window>>1), large_mss = max((tp->max_window>>1),
68U - tp->tcp_header_len); 68U - tp->tcp_header_len);
/* 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.
*/
factor = large_mss / mss_now; factor = large_mss / mss_now;
if (factor > (tp->snd_cwnd >> 2))
factor = max(1, tp->snd_cwnd >> 2); /* Always keep large mss multiple of real mss, but
* do not exceed 1/tso_win_divisor of the congestion window
* so we can keep the ACK clock ticking and minimize
* bursting.
*/
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; tp->mss_cache = mss_now * factor;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment