aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_memcontrol.c')
-rw-r--r--net/ipv4/tcp_memcontrol.c90
1 files changed, 18 insertions, 72 deletions
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 559d4ae6ebf4..03e9154f7e68 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -6,15 +6,10 @@
6#include <linux/memcontrol.h> 6#include <linux/memcontrol.h>
7#include <linux/module.h> 7#include <linux/module.h>
8 8
9static inline struct tcp_memcontrol *tcp_from_cgproto(struct cg_proto *cg_proto)
10{
11 return container_of(cg_proto, struct tcp_memcontrol, cg_proto);
12}
13
14static void memcg_tcp_enter_memory_pressure(struct sock *sk) 9static void memcg_tcp_enter_memory_pressure(struct sock *sk)
15{ 10{
16 if (sk->sk_cgrp->memory_pressure) 11 if (sk->sk_cgrp->memory_pressure)
17 *sk->sk_cgrp->memory_pressure = 1; 12 sk->sk_cgrp->memory_pressure = 1;
18} 13}
19EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure); 14EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
20 15
@@ -27,34 +22,24 @@ int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
27 */ 22 */
28 struct res_counter *res_parent = NULL; 23 struct res_counter *res_parent = NULL;
29 struct cg_proto *cg_proto, *parent_cg; 24 struct cg_proto *cg_proto, *parent_cg;
30 struct tcp_memcontrol *tcp;
31 struct mem_cgroup *parent = parent_mem_cgroup(memcg); 25 struct mem_cgroup *parent = parent_mem_cgroup(memcg);
32 struct net *net = current->nsproxy->net_ns;
33 26
34 cg_proto = tcp_prot.proto_cgroup(memcg); 27 cg_proto = tcp_prot.proto_cgroup(memcg);
35 if (!cg_proto) 28 if (!cg_proto)
36 return 0; 29 return 0;
37 30
38 tcp = tcp_from_cgproto(cg_proto); 31 cg_proto->sysctl_mem[0] = sysctl_tcp_mem[0];
39 32 cg_proto->sysctl_mem[1] = sysctl_tcp_mem[1];
40 tcp->tcp_prot_mem[0] = net->ipv4.sysctl_tcp_mem[0]; 33 cg_proto->sysctl_mem[2] = sysctl_tcp_mem[2];
41 tcp->tcp_prot_mem[1] = net->ipv4.sysctl_tcp_mem[1]; 34 cg_proto->memory_pressure = 0;
42 tcp->tcp_prot_mem[2] = net->ipv4.sysctl_tcp_mem[2]; 35 cg_proto->memcg = memcg;
43 tcp->tcp_memory_pressure = 0;
44 36
45 parent_cg = tcp_prot.proto_cgroup(parent); 37 parent_cg = tcp_prot.proto_cgroup(parent);
46 if (parent_cg) 38 if (parent_cg)
47 res_parent = parent_cg->memory_allocated; 39 res_parent = &parent_cg->memory_allocated;
48
49 res_counter_init(&tcp->tcp_memory_allocated, res_parent);
50 percpu_counter_init(&tcp->tcp_sockets_allocated, 0);
51 40
52 cg_proto->enter_memory_pressure = memcg_tcp_enter_memory_pressure; 41 res_counter_init(&cg_proto->memory_allocated, res_parent);
53 cg_proto->memory_pressure = &tcp->tcp_memory_pressure; 42 percpu_counter_init(&cg_proto->sockets_allocated, 0);
54 cg_proto->sysctl_mem = tcp->tcp_prot_mem;
55 cg_proto->memory_allocated = &tcp->tcp_memory_allocated;
56 cg_proto->sockets_allocated = &tcp->tcp_sockets_allocated;
57 cg_proto->memcg = memcg;
58 43
59 return 0; 44 return 0;
60} 45}
@@ -63,21 +48,17 @@ EXPORT_SYMBOL(tcp_init_cgroup);
63void tcp_destroy_cgroup(struct mem_cgroup *memcg) 48void tcp_destroy_cgroup(struct mem_cgroup *memcg)
64{ 49{
65 struct cg_proto *cg_proto; 50 struct cg_proto *cg_proto;
66 struct tcp_memcontrol *tcp;
67 51
68 cg_proto = tcp_prot.proto_cgroup(memcg); 52 cg_proto = tcp_prot.proto_cgroup(memcg);
69 if (!cg_proto) 53 if (!cg_proto)
70 return; 54 return;
71 55
72 tcp = tcp_from_cgproto(cg_proto); 56 percpu_counter_destroy(&cg_proto->sockets_allocated);
73 percpu_counter_destroy(&tcp->tcp_sockets_allocated);
74} 57}
75EXPORT_SYMBOL(tcp_destroy_cgroup); 58EXPORT_SYMBOL(tcp_destroy_cgroup);
76 59
77static int tcp_update_limit(struct mem_cgroup *memcg, u64 val) 60static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
78{ 61{
79 struct net *net = current->nsproxy->net_ns;
80 struct tcp_memcontrol *tcp;
81 struct cg_proto *cg_proto; 62 struct cg_proto *cg_proto;
82 u64 old_lim; 63 u64 old_lim;
83 int i; 64 int i;
@@ -90,16 +71,14 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
90 if (val > RES_COUNTER_MAX) 71 if (val > RES_COUNTER_MAX)
91 val = RES_COUNTER_MAX; 72 val = RES_COUNTER_MAX;
92 73
93 tcp = tcp_from_cgproto(cg_proto); 74 old_lim = res_counter_read_u64(&cg_proto->memory_allocated, RES_LIMIT);
94 75 ret = res_counter_set_limit(&cg_proto->memory_allocated, val);
95 old_lim = res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
96 ret = res_counter_set_limit(&tcp->tcp_memory_allocated, val);
97 if (ret) 76 if (ret)
98 return ret; 77 return ret;
99 78
100 for (i = 0; i < 3; i++) 79 for (i = 0; i < 3; i++)
101 tcp->tcp_prot_mem[i] = min_t(long, val >> PAGE_SHIFT, 80 cg_proto->sysctl_mem[i] = min_t(long, val >> PAGE_SHIFT,
102 net->ipv4.sysctl_tcp_mem[i]); 81 sysctl_tcp_mem[i]);
103 82
104 if (val == RES_COUNTER_MAX) 83 if (val == RES_COUNTER_MAX)
105 clear_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags); 84 clear_bit(MEMCG_SOCK_ACTIVE, &cg_proto->flags);
@@ -156,28 +135,24 @@ static int tcp_cgroup_write(struct cgroup_subsys_state *css, struct cftype *cft,
156 135
157static u64 tcp_read_stat(struct mem_cgroup *memcg, int type, u64 default_val) 136static u64 tcp_read_stat(struct mem_cgroup *memcg, int type, u64 default_val)
158{ 137{
159 struct tcp_memcontrol *tcp;
160 struct cg_proto *cg_proto; 138 struct cg_proto *cg_proto;
161 139
162 cg_proto = tcp_prot.proto_cgroup(memcg); 140 cg_proto = tcp_prot.proto_cgroup(memcg);
163 if (!cg_proto) 141 if (!cg_proto)
164 return default_val; 142 return default_val;
165 143
166 tcp = tcp_from_cgproto(cg_proto); 144 return res_counter_read_u64(&cg_proto->memory_allocated, type);
167 return res_counter_read_u64(&tcp->tcp_memory_allocated, type);
168} 145}
169 146
170static u64 tcp_read_usage(struct mem_cgroup *memcg) 147static u64 tcp_read_usage(struct mem_cgroup *memcg)
171{ 148{
172 struct tcp_memcontrol *tcp;
173 struct cg_proto *cg_proto; 149 struct cg_proto *cg_proto;
174 150
175 cg_proto = tcp_prot.proto_cgroup(memcg); 151 cg_proto = tcp_prot.proto_cgroup(memcg);
176 if (!cg_proto) 152 if (!cg_proto)
177 return atomic_long_read(&tcp_memory_allocated) << PAGE_SHIFT; 153 return atomic_long_read(&tcp_memory_allocated) << PAGE_SHIFT;
178 154
179 tcp = tcp_from_cgproto(cg_proto); 155 return res_counter_read_u64(&cg_proto->memory_allocated, RES_USAGE);
180 return res_counter_read_u64(&tcp->tcp_memory_allocated, RES_USAGE);
181} 156}
182 157
183static u64 tcp_cgroup_read(struct cgroup_subsys_state *css, struct cftype *cft) 158static u64 tcp_cgroup_read(struct cgroup_subsys_state *css, struct cftype *cft)
@@ -205,54 +180,25 @@ static u64 tcp_cgroup_read(struct cgroup_subsys_state *css, struct cftype *cft)
205static int tcp_cgroup_reset(struct cgroup_subsys_state *css, unsigned int event) 180static int tcp_cgroup_reset(struct cgroup_subsys_state *css, unsigned int event)
206{ 181{
207 struct mem_cgroup *memcg; 182 struct mem_cgroup *memcg;
208 struct tcp_memcontrol *tcp;
209 struct cg_proto *cg_proto; 183 struct cg_proto *cg_proto;
210 184
211 memcg = mem_cgroup_from_css(css); 185 memcg = mem_cgroup_from_css(css);
212 cg_proto = tcp_prot.proto_cgroup(memcg); 186 cg_proto = tcp_prot.proto_cgroup(memcg);
213 if (!cg_proto) 187 if (!cg_proto)
214 return 0; 188 return 0;
215 tcp = tcp_from_cgproto(cg_proto);
216 189
217 switch (event) { 190 switch (event) {
218 case RES_MAX_USAGE: 191 case RES_MAX_USAGE:
219 res_counter_reset_max(&tcp->tcp_memory_allocated); 192 res_counter_reset_max(&cg_proto->memory_allocated);
220 break; 193 break;
221 case RES_FAILCNT: 194 case RES_FAILCNT:
222 res_counter_reset_failcnt(&tcp->tcp_memory_allocated); 195 res_counter_reset_failcnt(&cg_proto->memory_allocated);
223 break; 196 break;
224 } 197 }
225 198
226 return 0; 199 return 0;
227} 200}
228 201
229unsigned long long tcp_max_memory(const struct mem_cgroup *memcg)
230{
231 struct tcp_memcontrol *tcp;
232 struct cg_proto *cg_proto;
233
234 cg_proto = tcp_prot.proto_cgroup((struct mem_cgroup *)memcg);
235 if (!cg_proto)
236 return 0;
237
238 tcp = tcp_from_cgproto(cg_proto);
239 return res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
240}
241
242void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx)
243{
244 struct tcp_memcontrol *tcp;
245 struct cg_proto *cg_proto;
246
247 cg_proto = tcp_prot.proto_cgroup(memcg);
248 if (!cg_proto)
249 return;
250
251 tcp = tcp_from_cgproto(cg_proto);
252
253 tcp->tcp_prot_mem[idx] = val;
254}
255
256static struct cftype tcp_files[] = { 202static struct cftype tcp_files[] = {
257 { 203 {
258 .name = "kmem.tcp.limit_in_bytes", 204 .name = "kmem.tcp.limit_in_bytes",