aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/ipv4.h1
-rw-r--r--include/net/tcp.h1
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c51
-rw-r--r--net/ipv4/tcp.c11
-rw-r--r--net/ipv4/tcp_ipv4.c1
-rw-r--r--net/ipv4/tcp_memcontrol.c9
-rw-r--r--net/ipv6/af_inet6.c2
-rw-r--r--net/ipv6/tcp_ipv6.c1
9 files changed, 57 insertions, 22 deletions
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index d786b4fc02a4..bbd023a1c9b9 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -55,6 +55,7 @@ struct netns_ipv4 {
55 int current_rt_cache_rebuild_count; 55 int current_rt_cache_rebuild_count;
56 56
57 unsigned int sysctl_ping_group_range[2]; 57 unsigned int sysctl_ping_group_range[2];
58 long sysctl_tcp_mem[3];
58 59
59 atomic_t rt_genid; 60 atomic_t rt_genid;
60 atomic_t dev_addr_genid; 61 atomic_t dev_addr_genid;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 913473b4eda7..a4f52e154843 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -230,7 +230,6 @@ extern int sysctl_tcp_fack;
230extern int sysctl_tcp_reordering; 230extern int sysctl_tcp_reordering;
231extern int sysctl_tcp_ecn; 231extern int sysctl_tcp_ecn;
232extern int sysctl_tcp_dsack; 232extern int sysctl_tcp_dsack;
233extern long sysctl_tcp_mem[3];
234extern int sysctl_tcp_wmem[3]; 233extern int sysctl_tcp_wmem[3];
235extern int sysctl_tcp_rmem[3]; 234extern int sysctl_tcp_rmem[3];
236extern int sysctl_tcp_app_win; 235extern int sysctl_tcp_app_win;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 15dc4c4828de..f7b5670744f0 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1672,6 +1672,8 @@ static int __init inet_init(void)
1672 ip_static_sysctl_init(); 1672 ip_static_sysctl_init();
1673#endif 1673#endif
1674 1674
1675 tcp_prot.sysctl_mem = init_net.ipv4.sysctl_tcp_mem;
1676
1675 /* 1677 /*
1676 * Add all the base protocols. 1678 * Add all the base protocols.
1677 */ 1679 */
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 69fd7201129a..bbd67abcb51d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -14,6 +14,7 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/nsproxy.h> 16#include <linux/nsproxy.h>
17#include <linux/swap.h>
17#include <net/snmp.h> 18#include <net/snmp.h>
18#include <net/icmp.h> 19#include <net/icmp.h>
19#include <net/ip.h> 20#include <net/ip.h>
@@ -174,6 +175,36 @@ static int proc_allowed_congestion_control(ctl_table *ctl,
174 return ret; 175 return ret;
175} 176}
176 177
178static int ipv4_tcp_mem(ctl_table *ctl, int write,
179 void __user *buffer, size_t *lenp,
180 loff_t *ppos)
181{
182 int ret;
183 unsigned long vec[3];
184 struct net *net = current->nsproxy->net_ns;
185
186 ctl_table tmp = {
187 .data = &vec,
188 .maxlen = sizeof(vec),
189 .mode = ctl->mode,
190 };
191
192 if (!write) {
193 ctl->data = &net->ipv4.sysctl_tcp_mem;
194 return proc_doulongvec_minmax(ctl, write, buffer, lenp, ppos);
195 }
196
197 ret = proc_doulongvec_minmax(&tmp, write, buffer, lenp, ppos);
198 if (ret)
199 return ret;
200
201 net->ipv4.sysctl_tcp_mem[0] = vec[0];
202 net->ipv4.sysctl_tcp_mem[1] = vec[1];
203 net->ipv4.sysctl_tcp_mem[2] = vec[2];
204
205 return 0;
206}
207
177static struct ctl_table ipv4_table[] = { 208static struct ctl_table ipv4_table[] = {
178 { 209 {
179 .procname = "tcp_timestamps", 210 .procname = "tcp_timestamps",
@@ -433,13 +464,6 @@ static struct ctl_table ipv4_table[] = {
433 .proc_handler = proc_dointvec 464 .proc_handler = proc_dointvec
434 }, 465 },
435 { 466 {
436 .procname = "tcp_mem",
437 .data = &sysctl_tcp_mem,
438 .maxlen = sizeof(sysctl_tcp_mem),
439 .mode = 0644,
440 .proc_handler = proc_doulongvec_minmax
441 },
442 {
443 .procname = "tcp_wmem", 467 .procname = "tcp_wmem",
444 .data = &sysctl_tcp_wmem, 468 .data = &sysctl_tcp_wmem,
445 .maxlen = sizeof(sysctl_tcp_wmem), 469 .maxlen = sizeof(sysctl_tcp_wmem),
@@ -721,6 +745,12 @@ static struct ctl_table ipv4_net_table[] = {
721 .mode = 0644, 745 .mode = 0644,
722 .proc_handler = ipv4_ping_group_range, 746 .proc_handler = ipv4_ping_group_range,
723 }, 747 },
748 {
749 .procname = "tcp_mem",
750 .maxlen = sizeof(init_net.ipv4.sysctl_tcp_mem),
751 .mode = 0644,
752 .proc_handler = ipv4_tcp_mem,
753 },
724 { } 754 { }
725}; 755};
726 756
@@ -734,6 +764,7 @@ EXPORT_SYMBOL_GPL(net_ipv4_ctl_path);
734static __net_init int ipv4_sysctl_init_net(struct net *net) 764static __net_init int ipv4_sysctl_init_net(struct net *net)
735{ 765{
736 struct ctl_table *table; 766 struct ctl_table *table;
767 unsigned long limit;
737 768
738 table = ipv4_net_table; 769 table = ipv4_net_table;
739 if (!net_eq(net, &init_net)) { 770 if (!net_eq(net, &init_net)) {
@@ -769,6 +800,12 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
769 800
770 net->ipv4.sysctl_rt_cache_rebuild_count = 4; 801 net->ipv4.sysctl_rt_cache_rebuild_count = 4;
771 802
803 limit = nr_free_buffer_pages() / 8;
804 limit = max(limit, 128UL);
805 net->ipv4.sysctl_tcp_mem[0] = limit / 4 * 3;
806 net->ipv4.sysctl_tcp_mem[1] = limit;
807 net->ipv4.sysctl_tcp_mem[2] = net->ipv4.sysctl_tcp_mem[0] * 2;
808
772 net->ipv4.ipv4_hdr = register_net_sysctl_table(net, 809 net->ipv4.ipv4_hdr = register_net_sysctl_table(net,
773 net_ipv4_ctl_path, table); 810 net_ipv4_ctl_path, table);
774 if (net->ipv4.ipv4_hdr == NULL) 811 if (net->ipv4.ipv4_hdr == NULL)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 43dfccce62e9..9bcdec3ad772 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -282,11 +282,9 @@ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
282struct percpu_counter tcp_orphan_count; 282struct percpu_counter tcp_orphan_count;
283EXPORT_SYMBOL_GPL(tcp_orphan_count); 283EXPORT_SYMBOL_GPL(tcp_orphan_count);
284 284
285long sysctl_tcp_mem[3] __read_mostly;
286int sysctl_tcp_wmem[3] __read_mostly; 285int sysctl_tcp_wmem[3] __read_mostly;
287int sysctl_tcp_rmem[3] __read_mostly; 286int sysctl_tcp_rmem[3] __read_mostly;
288 287
289EXPORT_SYMBOL(sysctl_tcp_mem);
290EXPORT_SYMBOL(sysctl_tcp_rmem); 288EXPORT_SYMBOL(sysctl_tcp_rmem);
291EXPORT_SYMBOL(sysctl_tcp_wmem); 289EXPORT_SYMBOL(sysctl_tcp_wmem);
292 290
@@ -3278,14 +3276,9 @@ void __init tcp_init(void)
3278 sysctl_tcp_max_orphans = cnt / 2; 3276 sysctl_tcp_max_orphans = cnt / 2;
3279 sysctl_max_syn_backlog = max(128, cnt / 256); 3277 sysctl_max_syn_backlog = max(128, cnt / 256);
3280 3278
3281 limit = nr_free_buffer_pages() / 8;
3282 limit = max(limit, 128UL);
3283 sysctl_tcp_mem[0] = limit / 4 * 3;
3284 sysctl_tcp_mem[1] = limit;
3285 sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2;
3286
3287 /* Set per-socket limits to no more than 1/128 the pressure threshold */ 3279 /* Set per-socket limits to no more than 1/128 the pressure threshold */
3288 limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); 3280 limit = ((unsigned long)init_net.ipv4.sysctl_tcp_mem[1])
3281 << (PAGE_SHIFT - 7);
3289 max_share = min(4UL*1024*1024, limit); 3282 max_share = min(4UL*1024*1024, limit);
3290 3283
3291 sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; 3284 sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 42714cb1fef3..1eb4ad57670e 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2623,7 +2623,6 @@ struct proto tcp_prot = {
2623 .orphan_count = &tcp_orphan_count, 2623 .orphan_count = &tcp_orphan_count,
2624 .memory_allocated = &tcp_memory_allocated, 2624 .memory_allocated = &tcp_memory_allocated,
2625 .memory_pressure = &tcp_memory_pressure, 2625 .memory_pressure = &tcp_memory_pressure,
2626 .sysctl_mem = sysctl_tcp_mem,
2627 .sysctl_wmem = sysctl_tcp_wmem, 2626 .sysctl_wmem = sysctl_tcp_wmem,
2628 .sysctl_rmem = sysctl_tcp_rmem, 2627 .sysctl_rmem = sysctl_tcp_rmem,
2629 .max_header = MAX_TCP_HEADER, 2628 .max_header = MAX_TCP_HEADER,
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 4a68d2c24556..bfb0c2b8df46 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -1,6 +1,8 @@
1#include <net/tcp.h> 1#include <net/tcp.h>
2#include <net/tcp_memcontrol.h> 2#include <net/tcp_memcontrol.h>
3#include <net/sock.h> 3#include <net/sock.h>
4#include <net/ip.h>
5#include <linux/nsproxy.h>
4#include <linux/memcontrol.h> 6#include <linux/memcontrol.h>
5#include <linux/module.h> 7#include <linux/module.h>
6 8
@@ -28,6 +30,7 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
28 struct tcp_memcontrol *tcp; 30 struct tcp_memcontrol *tcp;
29 struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp); 31 struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
30 struct mem_cgroup *parent = parent_mem_cgroup(memcg); 32 struct mem_cgroup *parent = parent_mem_cgroup(memcg);
33 struct net *net = current->nsproxy->net_ns;
31 34
32 cg_proto = tcp_prot.proto_cgroup(memcg); 35 cg_proto = tcp_prot.proto_cgroup(memcg);
33 if (!cg_proto) 36 if (!cg_proto)
@@ -35,9 +38,9 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
35 38
36 tcp = tcp_from_cgproto(cg_proto); 39 tcp = tcp_from_cgproto(cg_proto);
37 40
38 tcp->tcp_prot_mem[0] = sysctl_tcp_mem[0]; 41 tcp->tcp_prot_mem[0] = net->ipv4.sysctl_tcp_mem[0];
39 tcp->tcp_prot_mem[1] = sysctl_tcp_mem[1]; 42 tcp->tcp_prot_mem[1] = net->ipv4.sysctl_tcp_mem[1];
40 tcp->tcp_prot_mem[2] = sysctl_tcp_mem[2]; 43 tcp->tcp_prot_mem[2] = net->ipv4.sysctl_tcp_mem[2];
41 tcp->tcp_memory_pressure = 0; 44 tcp->tcp_memory_pressure = 0;
42 45
43 parent_cg = tcp_prot.proto_cgroup(parent); 46 parent_cg = tcp_prot.proto_cgroup(parent);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 7694c82e629d..273f48d1df2e 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -1116,6 +1116,8 @@ static int __init inet6_init(void)
1116 if (err) 1116 if (err)
1117 goto static_sysctl_fail; 1117 goto static_sysctl_fail;
1118#endif 1118#endif
1119 tcpv6_prot.sysctl_mem = init_net.ipv4.sysctl_tcp_mem;
1120
1119 /* 1121 /*
1120 * ipngwg API draft makes clear that the correct semantics 1122 * ipngwg API draft makes clear that the correct semantics
1121 * for TCP and UDP is to consider one TCP and UDP instance 1123 * for TCP and UDP is to consider one TCP and UDP instance
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 95d3cfb65d39..906c7ca43542 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2215,7 +2215,6 @@ struct proto tcpv6_prot = {
2215 .memory_allocated = &tcp_memory_allocated, 2215 .memory_allocated = &tcp_memory_allocated,
2216 .memory_pressure = &tcp_memory_pressure, 2216 .memory_pressure = &tcp_memory_pressure,
2217 .orphan_count = &tcp_orphan_count, 2217 .orphan_count = &tcp_orphan_count,
2218 .sysctl_mem = sysctl_tcp_mem,
2219 .sysctl_wmem = sysctl_tcp_wmem, 2218 .sysctl_wmem = sysctl_tcp_wmem,
2220 .sysctl_rmem = sysctl_tcp_rmem, 2219 .sysctl_rmem = sysctl_tcp_rmem,
2221 .max_header = MAX_TCP_HEADER, 2220 .max_header = MAX_TCP_HEADER,