aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.cz>2013-07-08 19:00:29 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-21 21:21:36 -0400
commit71a429cf00c7ff8da3fc3356617987e746055c00 (patch)
treec9a7d62dfc9a119ae11f3186c392e07d34a2cedb /mm
parentc14a4eaf8a43a295176942c7a43a999b4557f7c3 (diff)
memcg, kmem: fix reference count handling on the error path
commit f37a96914d1aea10fed8d9af10251f0b9caea31b upstream. mem_cgroup_css_online calls mem_cgroup_put if memcg_init_kmem fails. This is not correct because only memcg_propagate_kmem takes an additional reference while mem_cgroup_sockets_init is allowed to fail as well (although no current implementation fails) but it doesn't take any reference. This all suggests that it should be memcg_propagate_kmem that should clean up after itself so this patch moves mem_cgroup_put over there. Unfortunately this is not that easy (as pointed out by Li Zefan) because memcg_kmem_mark_dead marks the group dead (KMEM_ACCOUNTED_DEAD) if it is marked active (KMEM_ACCOUNTED_ACTIVE) which is the case even if memcg_propagate_kmem fails so the additional reference is dropped in that case in kmem_cgroup_destroy which means that the reference would be dropped two times. The easiest way then would be to simply remove mem_cgrroup_put from mem_cgroup_css_online and rely on kmem_cgroup_destroy doing the right thing. Signed-off-by: Michal Hocko <mhocko@suse.cz> Signed-off-by: Li Zefan <lizefan@huawei.com> Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Hugh Dickins <hughd@google.com> Cc: Tejun Heo <tj@kernel.org> Cc: Glauber Costa <glommer@openvz.org> Cc: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c8
1 files changed, 0 insertions, 8 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index fd79df5d3152..15b040904dc3 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6296,14 +6296,6 @@ mem_cgroup_css_online(struct cgroup *cont)
6296 6296
6297 error = memcg_init_kmem(memcg, &mem_cgroup_subsys); 6297 error = memcg_init_kmem(memcg, &mem_cgroup_subsys);
6298 mutex_unlock(&memcg_create_mutex); 6298 mutex_unlock(&memcg_create_mutex);
6299 if (error) {
6300 /*
6301 * We call put now because our (and parent's) refcnts
6302 * are already in place. mem_cgroup_put() will internally
6303 * call __mem_cgroup_free, so return directly
6304 */
6305 mem_cgroup_put(memcg);
6306 }
6307 return error; 6299 return error;
6308} 6300}
6309 6301