aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorGlauber Costa <glommer@parallels.com>2012-12-18 17:22:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-18 18:02:13 -0500
commitbea207c86e4eb158bf20f7b36bee72da9272e8d3 (patch)
tree9e100534378fa916f739b6a595508b40eabc35c0 /mm
parenta8964b9b84f99c0b1b5d7c09520f89f0700e742e (diff)
memcg: allow a memcg with kmem charges to be destructed
Because the ultimate goal of the kmem tracking in memcg is to track slab pages as well, we can't guarantee that we'll always be able to point a page to a particular process, and migrate the charges along with it - since in the common case, a page will contain data belonging to multiple processes. Because of that, when we destroy a memcg, we only make sure the destruction will succeed by discounting the kmem charges from the user charges when we try to empty the cgroup. Signed-off-by: Glauber Costa <glommer@parallels.com> Acked-by: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Reviewed-by: Michal Hocko <mhocko@suse.cz> Cc: Christoph Lameter <cl@linux.com> Cc: David Rientjes <rientjes@google.com> Cc: Frederic Weisbecker <fweisbec@redhat.com> Cc: Greg Thelen <gthelen@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: JoonSoo Kim <js1304@gmail.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Pekka Enberg <penberg@cs.helsinki.fi> Cc: Rik van Riel <riel@redhat.com> Cc: Suleiman Souhlal <suleiman@google.com> Cc: Tejun Heo <tj@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bc70254558fa..f96ccc90fa66 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -547,6 +547,11 @@ static void disarm_kmem_keys(struct mem_cgroup *memcg)
547{ 547{
548 if (memcg_kmem_is_active(memcg)) 548 if (memcg_kmem_is_active(memcg))
549 static_key_slow_dec(&memcg_kmem_enabled_key); 549 static_key_slow_dec(&memcg_kmem_enabled_key);
550 /*
551 * This check can't live in kmem destruction function,
552 * since the charges will outlive the cgroup
553 */
554 WARN_ON(res_counter_read_u64(&memcg->kmem, RES_USAGE) != 0);
550} 555}
551#else 556#else
552static void disarm_kmem_keys(struct mem_cgroup *memcg) 557static void disarm_kmem_keys(struct mem_cgroup *memcg)
@@ -4025,6 +4030,7 @@ static void mem_cgroup_force_empty_list(struct mem_cgroup *memcg,
4025static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg) 4030static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
4026{ 4031{
4027 int node, zid; 4032 int node, zid;
4033 u64 usage;
4028 4034
4029 do { 4035 do {
4030 /* This is for making all *used* pages to be on LRU. */ 4036 /* This is for making all *used* pages to be on LRU. */
@@ -4045,13 +4051,20 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
4045 cond_resched(); 4051 cond_resched();
4046 4052
4047 /* 4053 /*
4054 * Kernel memory may not necessarily be trackable to a specific
4055 * process. So they are not migrated, and therefore we can't
4056 * expect their value to drop to 0 here.
4057 * Having res filled up with kmem only is enough.
4058 *
4048 * This is a safety check because mem_cgroup_force_empty_list 4059 * This is a safety check because mem_cgroup_force_empty_list
4049 * could have raced with mem_cgroup_replace_page_cache callers 4060 * could have raced with mem_cgroup_replace_page_cache callers
4050 * so the lru seemed empty but the page could have been added 4061 * so the lru seemed empty but the page could have been added
4051 * right after the check. RES_USAGE should be safe as we always 4062 * right after the check. RES_USAGE should be safe as we always
4052 * charge before adding to the LRU. 4063 * charge before adding to the LRU.
4053 */ 4064 */
4054 } while (res_counter_read_u64(&memcg->res, RES_USAGE) > 0); 4065 usage = res_counter_read_u64(&memcg->res, RES_USAGE) -
4066 res_counter_read_u64(&memcg->kmem, RES_USAGE);
4067 } while (usage > 0);
4055} 4068}
4056 4069
4057/* 4070/*