aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorGlauber Costa <glommer@parallels.com>2011-12-11 16:47:03 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-12 19:04:10 -0500
commite1aab161e0135aafcd439be20b4f35e4b0922d95 (patch)
treed0bcdf7a34a34020079238027b431ffc6dece307 /mm/memcontrol.c
parent180d8cd942ce336b2c869d324855c40c5db478ad (diff)
socket: initial cgroup code.
The goal of this work is to move the memory pressure tcp controls to a cgroup, instead of just relying on global conditions. To avoid excessive overhead in the network fast paths, the code that accounts allocated memory to a cgroup is hidden inside a static_branch(). This branch is patched out until the first non-root cgroup is created. So when nobody is using cgroups, even if it is mounted, no significant performance penalty should be seen. This patch handles the generic part of the code, and has nothing tcp-specific. Signed-off-by: Glauber Costa <glommer@parallels.com> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujtsu.com> CC: Kirill A. Shutemov <kirill@shutemov.name> CC: David S. Miller <davem@davemloft.net> CC: Eric W. Biederman <ebiederm@xmission.com> CC: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 9fbcff71245e..3de3901ae0a7 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -379,7 +379,48 @@ enum mem_type {
379 379
380static void mem_cgroup_get(struct mem_cgroup *memcg); 380static void mem_cgroup_get(struct mem_cgroup *memcg);
381static void mem_cgroup_put(struct mem_cgroup *memcg); 381static void mem_cgroup_put(struct mem_cgroup *memcg);
382static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg); 382
383/* Writing them here to avoid exposing memcg's inner layout */
384#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
385#ifdef CONFIG_INET
386#include <net/sock.h>
387
388static bool mem_cgroup_is_root(struct mem_cgroup *memcg);
389void sock_update_memcg(struct sock *sk)
390{
391 /* A socket spends its whole life in the same cgroup */
392 if (sk->sk_cgrp) {
393 WARN_ON(1);
394 return;
395 }
396 if (static_branch(&memcg_socket_limit_enabled)) {
397 struct mem_cgroup *memcg;
398
399 BUG_ON(!sk->sk_prot->proto_cgroup);
400
401 rcu_read_lock();
402 memcg = mem_cgroup_from_task(current);
403 if (!mem_cgroup_is_root(memcg)) {
404 mem_cgroup_get(memcg);
405 sk->sk_cgrp = sk->sk_prot->proto_cgroup(memcg);
406 }
407 rcu_read_unlock();
408 }
409}
410EXPORT_SYMBOL(sock_update_memcg);
411
412void sock_release_memcg(struct sock *sk)
413{
414 if (static_branch(&memcg_socket_limit_enabled) && sk->sk_cgrp) {
415 struct mem_cgroup *memcg;
416 WARN_ON(!sk->sk_cgrp->memcg);
417 memcg = sk->sk_cgrp->memcg;
418 mem_cgroup_put(memcg);
419 }
420}
421#endif /* CONFIG_INET */
422#endif /* CONFIG_CGROUP_MEM_RES_CTLR_KMEM */
423
383static void drain_all_stock_async(struct mem_cgroup *memcg); 424static void drain_all_stock_async(struct mem_cgroup *memcg);
384 425
385static struct mem_cgroup_per_zone * 426static struct mem_cgroup_per_zone *
@@ -4932,12 +4973,13 @@ static void mem_cgroup_put(struct mem_cgroup *memcg)
4932/* 4973/*
4933 * Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled. 4974 * Returns the parent mem_cgroup in memcgroup hierarchy with hierarchy enabled.
4934 */ 4975 */
4935static struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg) 4976struct mem_cgroup *parent_mem_cgroup(struct mem_cgroup *memcg)
4936{ 4977{
4937 if (!memcg->res.parent) 4978 if (!memcg->res.parent)
4938 return NULL; 4979 return NULL;
4939 return mem_cgroup_from_res_counter(memcg->res.parent, res); 4980 return mem_cgroup_from_res_counter(memcg->res.parent, res);
4940} 4981}
4982EXPORT_SYMBOL(parent_mem_cgroup);
4941 4983
4942#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP 4984#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
4943static void __init enable_swap_cgroup(void) 4985static void __init enable_swap_cgroup(void)