Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

net/tcp: Fix tcp memory limits initialization when !CONFIG_SYSCTL

sysctl_tcp_mem() initialization was moved to sysctl_tcp_ipv4.c
in commit 3dc43e3, 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>
  • Loading branch information...
commit 4acb41903b2f99f3dffd4c3df9acc84ca5942cb2 1 parent 8a8ee9a
Glauber Costa authored davem330 committed
2  include/net/tcp.h
@@ -311,6 +311,8 @@ extern struct proto tcp_prot;
311 311 #define TCP_ADD_STATS_USER(net, field, val) SNMP_ADD_STATS_USER((net)->mib.tcp_statistics, field, val)
312 312 #define TCP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.tcp_statistics, field, val)
313 313
  314 +extern void tcp_init_mem(struct net *net);
  315 +
314 316 extern void tcp_v4_err(struct sk_buff *skb, u32);
315 317
316 318 extern void tcp_shutdown (struct sock *sk, int how);
1  net/ipv4/sysctl_net_ipv4.c
@@ -814,6 +814,7 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
814 814
815 815 net->ipv4.sysctl_rt_cache_rebuild_count = 4;
816 816
  817 + tcp_init_mem(net);
817 818 limit = nr_free_buffer_pages() / 8;
818 819 limit = max(limit, 128UL);
819 820 net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3;
16 net/ipv4/tcp.c
@@ -3216,6 +3216,16 @@ static int __init set_thash_entries(char *str)
3216 3216 }
3217 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 3229 void __init tcp_init(void)
3220 3230 {
3221 3231 struct sk_buff *skb = NULL;
@@ -3276,9 +3286,9 @@ void __init tcp_init(void)
3276 3286 sysctl_tcp_max_orphans = cnt / 2;
3277 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 */
3280   - limit = ((unsigned long)init_net.ipv4.sysctl_tcp_mem[1])
3281   - << (PAGE_SHIFT - 7);
  3289 + tcp_init_mem(&init_net);
  3290 + limit = nr_free_buffer_pages() / 8;
  3291 + limit = max(limit, 128UL);
3282 3292 max_share = min(4UL*1024*1024, limit);
3283 3293
3284 3294 sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;

0 comments on commit 4acb419

Please sign in to comment.
Something went wrong with that request. Please try again.