When obj_cgroup_alloc() fails partway through the NUMA node loop in mem_cgroup_css_online(), the free_objcg error path drops the extra reference held by pn->orig_objcg but never kills the initial percpu_ref from obj_cgroup_alloc() stored in pn->objcg. Since css_offline is never called when css_online fails, memcg_reparent_objcgs() never runs, so the percpu_ref_kill() that normally drops this initial reference never executes. The obj_cgroup and its per-cpu ref allocations are leaked. Add the missing percpu_ref_kill() in the error path, matching the normal teardown sequence in memcg_reparent_objcgs(). Fixes: 098fad3e1621 ("mm: memcontrol: convert objcg to be per-memcg per-node type") Cc: stable@vger.kernel.org Signed-off-by: David Carlier --- mm/memcontrol.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index a47fb68dd65f..0da996d37c74 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -4100,8 +4100,9 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css) for_each_node(nid) { objcg = obj_cgroup_alloc(); - if (!objcg) + if (!objcg) { goto free_objcg; + } if (unlikely(mem_cgroup_is_root(memcg))) objcg->is_root = true; @@ -4137,6 +4138,9 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css) free_objcg: for_each_node(nid) { struct mem_cgroup_per_node *pn = memcg->nodeinfo[nid]; + objcg = rcu_dereference_protected(pn->objcg, true); + if (objcg) + percpu_ref_kill(&objcg->refcnt); if (pn && pn->orig_objcg) { obj_cgroup_put(pn->orig_objcg); -- 2.53.0