Skip to content

Commit

Permalink
tcp: add a sysctl to config the tcp_default_init_rwnd
Browse files Browse the repository at this point in the history
The default initial rwnd is hardcoded to 10.

Now we allow it to be controlled via
  /proc/sys/net/ipv4/tcp_default_init_rwnd
which limits the values from 3 to 100

This is somewhat needed because ipv6 routes are
autoconfigured by the kernel.

See "An Argument for Increasing TCP's Initial Congestion Window"
in https://developers.google.com/speed/articles/tcp_initcwnd_paper.pdf

Change-Id: I386b2a9d62de0ebe05c1ebe1b4bd91b314af5c54
Signed-off-by: JP Abgrall <jpa@google.com>

Conflicts:
	include/net/tcp.h
  • Loading branch information
jpa468 committed Feb 7, 2014
1 parent 26f062e commit 36eb1e1
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
1 change: 1 addition & 0 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ extern int sysctl_tcp_max_ssthresh;
extern int sysctl_tcp_cookie_size;
extern int sysctl_tcp_thin_linear_timeouts;
extern int sysctl_tcp_thin_dupack;
extern int sysctl_tcp_default_init_rwnd;

extern atomic_long_t tcp_memory_allocated;
extern struct percpu_counter tcp_sockets_allocated;
Expand Down
24 changes: 23 additions & 1 deletion net/ipv4/sysctl_net_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,21 @@ static int ipv4_ping_group_range(ctl_table *table, int write,
return ret;
}

/* Validate changes from /proc interface. */
static int proc_tcp_default_init_rwnd(ctl_table *ctl, int write,
void __user *buffer,
size_t *lenp, loff_t *ppos)
{
int old_value = *(int *)ctl->data;
int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
int new_value = *(int *)ctl->data;

if (write && ret == 0 && (new_value < 3 || new_value > 100))
*(int *)ctl->data = old_value;

return ret;
}

static int proc_tcp_congestion_control(ctl_table *ctl, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
Expand Down Expand Up @@ -669,13 +684,20 @@ static struct ctl_table ipv4_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec
},
{
{
.procname = "tcp_thin_dupack",
.data = &sysctl_tcp_thin_dupack,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
},
{
.procname = "tcp_default_init_rwnd",
.data = &sysctl_tcp_default_init_rwnd,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_tcp_default_init_rwnd
},
{
.procname = "udp_mem",
.data = &sysctl_udp_mem,
Expand Down
5 changes: 3 additions & 2 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ int sysctl_tcp_thin_dupack __read_mostly;

int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
int sysctl_tcp_abc __read_mostly;
int sysctl_tcp_default_init_rwnd __read_mostly = TCP_DEFAULT_INIT_RCVWND;

#define FLAG_DATA 0x01 /* Incoming frame contained data. */
#define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
Expand Down Expand Up @@ -348,14 +349,14 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb)
static void tcp_fixup_rcvbuf(struct sock *sk)
{
u32 mss = tcp_sk(sk)->advmss;
u32 icwnd = TCP_DEFAULT_INIT_RCVWND;
u32 icwnd = sysctl_tcp_default_init_rwnd;
int rcvmem;

/* Limit to 10 segments if mss <= 1460,
* or 14600/mss segments, with a minimum of two segments.
*/
if (mss > 1460)
icwnd = max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
icwnd = max_t(u32, (1460 * icwnd) / mss, 2);

rcvmem = SKB_TRUESIZE(mss + MAX_TCP_HEADER);
while (tcp_win_from_space(rcvmem) < mss)
Expand Down
7 changes: 3 additions & 4 deletions net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,13 @@ void tcp_select_initial_window(int __space, __u32 mss,
}

/* Set initial window to a value enough for senders starting with
* initial congestion window of TCP_DEFAULT_INIT_RCVWND. Place
* initial congestion window of sysctl_tcp_default_init_rwnd. Place
* a limit on the initial window when mss is larger than 1460.
*/
if (mss > (1 << *rcv_wscale)) {
int init_cwnd = TCP_DEFAULT_INIT_RCVWND;
int init_cwnd = sysctl_tcp_default_init_rwnd;
if (mss > 1460)
init_cwnd =
max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);
init_cwnd = max_t(u32, (1460 * init_cwnd) / mss, 2);
/* when initializing use the value from init_rcv_wnd
* rather than the default from above
*/
Expand Down

0 comments on commit 36eb1e1

Please sign in to comment.