aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorGlauber Costa <glommer@parallels.com>2011-12-11 16:47:04 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-12 19:04:10 -0500
commitd1a4c0b37c296e600ffe08edb0db2dc1b8f550d7 (patch)
tree5c3675582cbbdc99f720aa1dcc1821e26c2be1ab /mm/memcontrol.c
parente1aab161e0135aafcd439be20b4f35e4b0922d95 (diff)
tcp memory pressure controls
This patch introduces memory pressure controls for the tcp protocol. It uses the generic socket memory pressure code introduced in earlier patches, and fills in the necessary data in cg_proto struct. Signed-off-by: Glauber Costa <glommer@parallels.com> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujtisu.com> CC: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3de3901ae0a7..7266202fa7cf 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -50,6 +50,8 @@
50#include <linux/cpu.h> 50#include <linux/cpu.h>
51#include <linux/oom.h> 51#include <linux/oom.h>
52#include "internal.h" 52#include "internal.h"
53#include <net/sock.h>
54#include <net/tcp_memcontrol.h>
53 55
54#include <asm/uaccess.h> 56#include <asm/uaccess.h>
55 57
@@ -295,6 +297,10 @@ struct mem_cgroup {
295 */ 297 */
296 struct mem_cgroup_stat_cpu nocpu_base; 298 struct mem_cgroup_stat_cpu nocpu_base;
297 spinlock_t pcp_counter_lock; 299 spinlock_t pcp_counter_lock;
300
301#ifdef CONFIG_INET
302 struct tcp_memcontrol tcp_mem;
303#endif
298}; 304};
299 305
300/* Stuffs for move charges at task migration. */ 306/* Stuffs for move charges at task migration. */
@@ -384,6 +390,7 @@ static void mem_cgroup_put(struct mem_cgroup *memcg);
384#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM 390#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
385#ifdef CONFIG_INET 391#ifdef CONFIG_INET
386#include <net/sock.h> 392#include <net/sock.h>
393#include <net/ip.h>
387 394
388static bool mem_cgroup_is_root(struct mem_cgroup *memcg); 395static bool mem_cgroup_is_root(struct mem_cgroup *memcg);
389void sock_update_memcg(struct sock *sk) 396void sock_update_memcg(struct sock *sk)
@@ -418,6 +425,15 @@ void sock_release_memcg(struct sock *sk)
418 mem_cgroup_put(memcg); 425 mem_cgroup_put(memcg);
419 } 426 }
420} 427}
428
429struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg)
430{
431 if (!memcg || mem_cgroup_is_root(memcg))
432 return NULL;
433
434 return &memcg->tcp_mem.cg_proto;
435}
436EXPORT_SYMBOL(tcp_proto_cgroup);
421#endif /* CONFIG_INET */ 437#endif /* CONFIG_INET */
422#endif /* CONFIG_CGROUP_MEM_RES_CTLR_KMEM */ 438#endif /* CONFIG_CGROUP_MEM_RES_CTLR_KMEM */
423 439
@@ -800,7 +816,7 @@ static void memcg_check_events(struct mem_cgroup *memcg, struct page *page)
800 preempt_enable(); 816 preempt_enable();
801} 817}
802 818
803static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) 819struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
804{ 820{
805 return container_of(cgroup_subsys_state(cont, 821 return container_of(cgroup_subsys_state(cont,
806 mem_cgroup_subsys_id), struct mem_cgroup, 822 mem_cgroup_subsys_id), struct mem_cgroup,
@@ -4732,14 +4748,34 @@ static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
4732 4748
4733 ret = cgroup_add_files(cont, ss, kmem_cgroup_files, 4749 ret = cgroup_add_files(cont, ss, kmem_cgroup_files,
4734 ARRAY_SIZE(kmem_cgroup_files)); 4750 ARRAY_SIZE(kmem_cgroup_files));
4751
4752 /*
4753 * Part of this would be better living in a separate allocation
4754 * function, leaving us with just the cgroup tree population work.
4755 * We, however, depend on state such as network's proto_list that
4756 * is only initialized after cgroup creation. I found the less
4757 * cumbersome way to deal with it to defer it all to populate time
4758 */
4759 if (!ret)
4760 ret = mem_cgroup_sockets_init(cont, ss);
4735 return ret; 4761 return ret;
4736}; 4762};
4737 4763
4764static void kmem_cgroup_destroy(struct cgroup_subsys *ss,
4765 struct cgroup *cont)
4766{
4767 mem_cgroup_sockets_destroy(cont, ss);
4768}
4738#else 4769#else
4739static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss) 4770static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
4740{ 4771{
4741 return 0; 4772 return 0;
4742} 4773}
4774
4775static void kmem_cgroup_destroy(struct cgroup_subsys *ss,
4776 struct cgroup *cont)
4777{
4778}
4743#endif 4779#endif
4744 4780
4745static struct cftype mem_cgroup_files[] = { 4781static struct cftype mem_cgroup_files[] = {
@@ -5098,6 +5134,8 @@ static void mem_cgroup_destroy(struct cgroup_subsys *ss,
5098{ 5134{
5099 struct mem_cgroup *memcg = mem_cgroup_from_cont(cont); 5135 struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
5100 5136
5137 kmem_cgroup_destroy(ss, cont);
5138
5101 mem_cgroup_put(memcg); 5139 mem_cgroup_put(memcg);
5102} 5140}
5103 5141