diff options
author | Glauber Costa <glommer@parallels.com> | 2012-01-29 20:20:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-01-30 12:41:06 -0500 |
commit | 4acb41903b2f99f3dffd4c3df9acc84ca5942cb2 (patch) | |
tree | 3a2dc1739d654effecd86749e49a40d41019e645 /net | |
parent | 8a8ee9aff6c3077dd9c2c7a77478e8ed362b96c6 (diff) |
net/tcp: Fix tcp memory limits initialization when !CONFIG_SYSCTL
sysctl_tcp_mem() initialization was moved to sysctl_tcp_ipv4.c
in commit 3dc43e3e4d0b52197d3205214fe8f162f9e0c334, since it
became a per-ns value.
That code, however, will never run when CONFIG_SYSCTL is
disabled, leading to bogus values on those fields - causing hung
TCP sockets.
This patch fixes it by keeping an initialization code in
tcp_init(). It will be overwritten by the first net namespace
init if CONFIG_SYSCTL is compiled in, and do the right thing if
it is compiled out.
It is also named properly as tcp_init_mem(), to properly signal
its non-sysctl side effect on TCP limits.
Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Glauber Costa <glommer@parallels.com>
Cc: David S. Miller <davem@davemloft.net>
Link: http://lkml.kernel.org/r/4F22D05A.8030604@parallels.com
[ renamed the function, tidied up the changelog a bit ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 1 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 16 |
2 files changed, 14 insertions, 3 deletions
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 4aa7e9dc0cbb..4cb9cd2f2c39 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
@@ -814,6 +814,7 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) | |||
814 | 814 | ||
815 | net->ipv4.sysctl_rt_cache_rebuild_count = 4; | 815 | net->ipv4.sysctl_rt_cache_rebuild_count = 4; |
816 | 816 | ||
817 | tcp_init_mem(net); | ||
817 | limit = nr_free_buffer_pages() / 8; | 818 | limit = nr_free_buffer_pages() / 8; |
818 | limit = max(limit, 128UL); | 819 | limit = max(limit, 128UL); |
819 | net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3; | 820 | net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3; |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9bcdec3ad772..06373b4a449a 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -3216,6 +3216,16 @@ static int __init set_thash_entries(char *str) | |||
3216 | } | 3216 | } |
3217 | __setup("thash_entries=", set_thash_entries); | 3217 | __setup("thash_entries=", set_thash_entries); |
3218 | 3218 | ||
3219 | void tcp_init_mem(struct net *net) | ||
3220 | { | ||
3221 | /* Set per-socket limits to no more than 1/128 the pressure threshold */ | ||
3222 | unsigned long limit = nr_free_buffer_pages() / 8; | ||
3223 | limit = max(limit, 128UL); | ||
3224 | net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3; | ||
3225 | net->ipv4.sysctl_tcp_mem[1] = limit; | ||
3226 | net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2; | ||
3227 | } | ||
3228 | |||
3219 | void __init tcp_init(void) | 3229 | void __init tcp_init(void) |
3220 | { | 3230 | { |
3221 | struct sk_buff *skb = NULL; | 3231 | struct sk_buff *skb = NULL; |
@@ -3276,9 +3286,9 @@ void __init tcp_init(void) | |||
3276 | sysctl_tcp_max_orphans = cnt / 2; | 3286 | sysctl_tcp_max_orphans = cnt / 2; |
3277 | sysctl_max_syn_backlog = max(128, cnt / 256); | 3287 | sysctl_max_syn_backlog = max(128, cnt / 256); |
3278 | 3288 | ||
3279 | /* Set per-socket limits to no more than 1/128 the pressure threshold */ | 3289 | tcp_init_mem(&init_net); |
3280 | limit = ((unsigned long)init_net.ipv4.sysctl_tcp_mem[1]) | 3290 | limit = nr_free_buffer_pages() / 8; |
3281 | << (PAGE_SHIFT - 7); | 3291 | limit = max(limit, 128UL); |
3282 | max_share = min(4UL*1024*1024, limit); | 3292 | max_share = min(4UL*1024*1024, limit); |
3283 | 3293 | ||
3284 | sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; | 3294 | sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; |