d438fba31ba8c9ea3f0b13af97345d44e3ed3c13
[cascardo/linux.git] / net / ipv4 / tcp_memcontrol.c
1 #include <net/tcp.h>
2 #include <net/tcp_memcontrol.h>
3 #include <net/sock.h>
4 #include <net/ip.h>
5 #include <linux/nsproxy.h>
6 #include <linux/memcontrol.h>
7 #include <linux/module.h>
8
9 static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft);
10 static int tcp_cgroup_write(struct cgroup *cont, struct cftype *cft,
11                             const char *buffer);
12 static int tcp_cgroup_reset(struct cgroup *cont, unsigned int event);
13
14 static struct cftype tcp_files[] = {
15         {
16                 .name = "kmem.tcp.limit_in_bytes",
17                 .write_string = tcp_cgroup_write,
18                 .read_u64 = tcp_cgroup_read,
19                 .private = RES_LIMIT,
20         },
21         {
22                 .name = "kmem.tcp.usage_in_bytes",
23                 .read_u64 = tcp_cgroup_read,
24                 .private = RES_USAGE,
25         },
26         {
27                 .name = "kmem.tcp.failcnt",
28                 .private = RES_FAILCNT,
29                 .trigger = tcp_cgroup_reset,
30                 .read_u64 = tcp_cgroup_read,
31         },
32 };
33
34 static inline struct tcp_memcontrol *tcp_from_cgproto(struct cg_proto *cg_proto)
35 {
36         return container_of(cg_proto, struct tcp_memcontrol, cg_proto);
37 }
38
39 static void memcg_tcp_enter_memory_pressure(struct sock *sk)
40 {
41         if (!sk->sk_cgrp->memory_pressure)
42                 *sk->sk_cgrp->memory_pressure = 1;
43 }
44 EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
45
46 int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
47 {
48         /*
49          * The root cgroup does not use res_counters, but rather,
50          * rely on the data already collected by the network
51          * subsystem
52          */
53         struct res_counter *res_parent = NULL;
54         struct cg_proto *cg_proto, *parent_cg;
55         struct tcp_memcontrol *tcp;
56         struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
57         struct mem_cgroup *parent = parent_mem_cgroup(memcg);
58         struct net *net = current->nsproxy->net_ns;
59
60         cg_proto = tcp_prot.proto_cgroup(memcg);
61         if (!cg_proto)
62                 goto create_files;
63
64         tcp = tcp_from_cgproto(cg_proto);
65
66         tcp->tcp_prot_mem[0] = net->ipv4.sysctl_tcp_mem[0];
67         tcp->tcp_prot_mem[1] = net->ipv4.sysctl_tcp_mem[1];
68         tcp->tcp_prot_mem[2] = net->ipv4.sysctl_tcp_mem[2];
69         tcp->tcp_memory_pressure = 0;
70
71         parent_cg = tcp_prot.proto_cgroup(parent);
72         if (parent_cg)
73                 res_parent = parent_cg->memory_allocated;
74
75         res_counter_init(&tcp->tcp_memory_allocated, res_parent);
76         percpu_counter_init(&tcp->tcp_sockets_allocated, 0);
77
78         cg_proto->enter_memory_pressure = memcg_tcp_enter_memory_pressure;
79         cg_proto->memory_pressure = &tcp->tcp_memory_pressure;
80         cg_proto->sysctl_mem = tcp->tcp_prot_mem;
81         cg_proto->memory_allocated = &tcp->tcp_memory_allocated;
82         cg_proto->sockets_allocated = &tcp->tcp_sockets_allocated;
83         cg_proto->memcg = memcg;
84
85 create_files:
86         return cgroup_add_files(cgrp, ss, tcp_files,
87                                 ARRAY_SIZE(tcp_files));
88 }
89 EXPORT_SYMBOL(tcp_init_cgroup);
90
91 void tcp_destroy_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
92 {
93         struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
94         struct cg_proto *cg_proto;
95         struct tcp_memcontrol *tcp;
96         u64 val;
97
98         cg_proto = tcp_prot.proto_cgroup(memcg);
99         if (!cg_proto)
100                 return;
101
102         tcp = tcp_from_cgproto(cg_proto);
103         percpu_counter_destroy(&tcp->tcp_sockets_allocated);
104
105         val = res_counter_read_u64(&tcp->tcp_memory_allocated, RES_USAGE);
106
107         if (val != RESOURCE_MAX)
108                 jump_label_dec(&memcg_socket_limit_enabled);
109 }
110 EXPORT_SYMBOL(tcp_destroy_cgroup);
111
112 static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
113 {
114         struct net *net = current->nsproxy->net_ns;
115         struct tcp_memcontrol *tcp;
116         struct cg_proto *cg_proto;
117         u64 old_lim;
118         int i;
119         int ret;
120
121         cg_proto = tcp_prot.proto_cgroup(memcg);
122         if (!cg_proto)
123                 return -EINVAL;
124
125         if (val > RESOURCE_MAX)
126                 val = RESOURCE_MAX;
127
128         tcp = tcp_from_cgproto(cg_proto);
129
130         old_lim = res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
131         ret = res_counter_set_limit(&tcp->tcp_memory_allocated, val);
132         if (ret)
133                 return ret;
134
135         for (i = 0; i < 3; i++)
136                 tcp->tcp_prot_mem[i] = min_t(long, val >> PAGE_SHIFT,
137                                              net->ipv4.sysctl_tcp_mem[i]);
138
139         if (val == RESOURCE_MAX && old_lim != RESOURCE_MAX)
140                 jump_label_dec(&memcg_socket_limit_enabled);
141         else if (old_lim == RESOURCE_MAX && val != RESOURCE_MAX)
142                 jump_label_inc(&memcg_socket_limit_enabled);
143
144         return 0;
145 }
146
147 static int tcp_cgroup_write(struct cgroup *cont, struct cftype *cft,
148                             const char *buffer)
149 {
150         struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
151         unsigned long long val;
152         int ret = 0;
153
154         switch (cft->private) {
155         case RES_LIMIT:
156                 /* see memcontrol.c */
157                 ret = res_counter_memparse_write_strategy(buffer, &val);
158                 if (ret)
159                         break;
160                 ret = tcp_update_limit(memcg, val);
161                 break;
162         default:
163                 ret = -EINVAL;
164                 break;
165         }
166         return ret;
167 }
168
169 static u64 tcp_read_stat(struct mem_cgroup *memcg, int type, u64 default_val)
170 {
171         struct tcp_memcontrol *tcp;
172         struct cg_proto *cg_proto;
173
174         cg_proto = tcp_prot.proto_cgroup(memcg);
175         if (!cg_proto)
176                 return default_val;
177
178         tcp = tcp_from_cgproto(cg_proto);
179         return res_counter_read_u64(&tcp->tcp_memory_allocated, type);
180 }
181
182 static u64 tcp_read_usage(struct mem_cgroup *memcg)
183 {
184         struct tcp_memcontrol *tcp;
185         struct cg_proto *cg_proto;
186
187         cg_proto = tcp_prot.proto_cgroup(memcg);
188         if (!cg_proto)
189                 return atomic_long_read(&tcp_memory_allocated) << PAGE_SHIFT;
190
191         tcp = tcp_from_cgproto(cg_proto);
192         return res_counter_read_u64(&tcp->tcp_memory_allocated, RES_USAGE);
193 }
194
195 static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft)
196 {
197         struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
198         u64 val;
199
200         switch (cft->private) {
201         case RES_LIMIT:
202                 val = tcp_read_stat(memcg, RES_LIMIT, RESOURCE_MAX);
203                 break;
204         case RES_USAGE:
205                 val = tcp_read_usage(memcg);
206                 break;
207         case RES_FAILCNT:
208                 val = tcp_read_stat(memcg, RES_FAILCNT, 0);
209                 break;
210         default:
211                 BUG();
212         }
213         return val;
214 }
215
216 static int tcp_cgroup_reset(struct cgroup *cont, unsigned int event)
217 {
218         struct mem_cgroup *memcg;
219         struct tcp_memcontrol *tcp;
220         struct cg_proto *cg_proto;
221
222         memcg = mem_cgroup_from_cont(cont);
223         cg_proto = tcp_prot.proto_cgroup(memcg);
224         if (!cg_proto)
225                 return 0;
226         tcp = tcp_from_cgproto(cg_proto);
227
228         switch (event) {
229         case RES_FAILCNT:
230                 res_counter_reset_failcnt(&tcp->tcp_memory_allocated);
231                 break;
232         }
233
234         return 0;
235 }
236
237 unsigned long long tcp_max_memory(const struct mem_cgroup *memcg)
238 {
239         struct tcp_memcontrol *tcp;
240         struct cg_proto *cg_proto;
241
242         cg_proto = tcp_prot.proto_cgroup((struct mem_cgroup *)memcg);
243         if (!cg_proto)
244                 return 0;
245
246         tcp = tcp_from_cgproto(cg_proto);
247         return res_counter_read_u64(&tcp->tcp_memory_allocated, RES_LIMIT);
248 }
249
250 void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx)
251 {
252         struct tcp_memcontrol *tcp;
253         struct cg_proto *cg_proto;
254
255         cg_proto = tcp_prot.proto_cgroup(memcg);
256         if (!cg_proto)
257                 return;
258
259         tcp = tcp_from_cgproto(cg_proto);
260
261         tcp->tcp_prot_mem[idx] = val;
262 }