diff options
-rw-r--r-- | Documentation/cgroups/memory.txt | 1 | ||||
-rw-r--r-- | net/ipv4/tcp_memcontrol.c | 21 |
2 files changed, 22 insertions, 0 deletions
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt index 1c9779a74a25..6922b6cb58e3 100644 --- a/Documentation/cgroups/memory.txt +++ b/Documentation/cgroups/memory.txt | |||
@@ -79,6 +79,7 @@ Brief summary of control files. | |||
79 | memory.independent_kmem_limit # select whether or not kernel memory limits are | 79 | memory.independent_kmem_limit # select whether or not kernel memory limits are |
80 | independent of user limits | 80 | independent of user limits |
81 | memory.kmem.tcp.limit_in_bytes # set/show hard limit for tcp buf memory | 81 | memory.kmem.tcp.limit_in_bytes # set/show hard limit for tcp buf memory |
82 | memory.kmem.tcp.usage_in_bytes # show current tcp buf memory allocation | ||
82 | 83 | ||
83 | 1. History | 84 | 1. History |
84 | 85 | ||
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c index e3533903409d..9481f235803e 100644 --- a/net/ipv4/tcp_memcontrol.c +++ b/net/ipv4/tcp_memcontrol.c | |||
@@ -17,6 +17,11 @@ static struct cftype tcp_files[] = { | |||
17 | .read_u64 = tcp_cgroup_read, | 17 | .read_u64 = tcp_cgroup_read, |
18 | .private = RES_LIMIT, | 18 | .private = RES_LIMIT, |
19 | }, | 19 | }, |
20 | { | ||
21 | .name = "kmem.tcp.usage_in_bytes", | ||
22 | .read_u64 = tcp_cgroup_read, | ||
23 | .private = RES_USAGE, | ||
24 | }, | ||
20 | }; | 25 | }; |
21 | 26 | ||
22 | static inline struct tcp_memcontrol *tcp_from_cgproto(struct cg_proto *cg_proto) | 27 | static inline struct tcp_memcontrol *tcp_from_cgproto(struct cg_proto *cg_proto) |
@@ -167,6 +172,19 @@ static u64 tcp_read_stat(struct mem_cgroup *memcg, int type, u64 default_val) | |||
167 | return res_counter_read_u64(&tcp->tcp_memory_allocated, type); | 172 | return res_counter_read_u64(&tcp->tcp_memory_allocated, type); |
168 | } | 173 | } |
169 | 174 | ||
175 | static u64 tcp_read_usage(struct mem_cgroup *memcg) | ||
176 | { | ||
177 | struct tcp_memcontrol *tcp; | ||
178 | struct cg_proto *cg_proto; | ||
179 | |||
180 | cg_proto = tcp_prot.proto_cgroup(memcg); | ||
181 | if (!cg_proto) | ||
182 | return atomic_long_read(&tcp_memory_allocated) << PAGE_SHIFT; | ||
183 | |||
184 | tcp = tcp_from_cgproto(cg_proto); | ||
185 | return res_counter_read_u64(&tcp->tcp_memory_allocated, RES_USAGE); | ||
186 | } | ||
187 | |||
170 | static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft) | 188 | static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft) |
171 | { | 189 | { |
172 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); | 190 | struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); |
@@ -176,6 +194,9 @@ static u64 tcp_cgroup_read(struct cgroup *cont, struct cftype *cft) | |||
176 | case RES_LIMIT: | 194 | case RES_LIMIT: |
177 | val = tcp_read_stat(memcg, RES_LIMIT, RESOURCE_MAX); | 195 | val = tcp_read_stat(memcg, RES_LIMIT, RESOURCE_MAX); |
178 | break; | 196 | break; |
197 | case RES_USAGE: | ||
198 | val = tcp_read_usage(memcg); | ||
199 | break; | ||
179 | default: | 200 | default: |
180 | BUG(); | 201 | BUG(); |
181 | } | 202 | } |