diff options
author | Glauber Costa <glommer@parallels.com> | 2011-12-11 16:47:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-12 19:04:11 -0500 |
commit | 3dc43e3e4d0b52197d3205214fe8f162f9e0c334 (patch) | |
tree | 1770affeb483a6b4f06cde9f2a2f1289b41496d6 /net/ipv4/sysctl_net_ipv4.c | |
parent | d1a4c0b37c296e600ffe08edb0db2dc1b8f550d7 (diff) |
per-netns ipv4 sysctl_tcp_mem
This patch allows each namespace to independently set up
its levels for tcp memory pressure thresholds. This patch
alone does not buy much: we need to make this values
per group of process somehow. This is achieved in the
patches that follows in this patchset.
Signed-off-by: Glauber Costa <glommer@parallels.com>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
CC: David S. Miller <davem@davemloft.net>
CC: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/sysctl_net_ipv4.c')
-rw-r--r-- | net/ipv4/sysctl_net_ipv4.c | 51 |
1 files changed, 44 insertions, 7 deletions
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 | ||
178 | static 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 | |||
177 | static struct ctl_table ipv4_table[] = { | 208 | static 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); | |||
734 | static __net_init int ipv4_sysctl_init_net(struct net *net) | 764 | static __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) |