From: Kirill Tkhai <ktk...@virtuozzo.com> In case of memcg_online_kmem() failure, memcg_cgroup::id remains hashed in mem_cgroup_idr even after memcg memory is freed. This leads to leak of ID in mem_cgroup_idr.
This patch adds removal into mem_cgroup_css_alloc(), which fixes the problem. For better readability, it adds a generic helper which is used in mem_cgroup_alloc() and mem_cgroup_id_put_many() as well. Link: http://lkml.kernel.org/r/152354470916.22460.14397070748001974638.stgit@localhost.localdomain Fixes 73f576c04b94 ("mm: memcontrol: fix cgroup creation failure after many small jobs") Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> Acked-by: Johannes Weiner <han...@cmpxchg.org> Acked-by: Vladimir Davydov <vdavydov....@gmail.com> Cc: Michal Hocko <mho...@kernel.org> Signed-off-by: Andrew Morton <a...@linux-foundation.org> Signed-off-by: Linus Torvalds <torva...@linux-foundation.org> Changes: - skip hunk in mem_cgroup_css_alloc as there is no such error path yet, patch is not strictly required but better have it as a small cleanup https://jira.vzint.dev/browse/PSBM-147036 (cherry picked from commit 7e97de0b033bcac4fa9a35cef72e0c06e6a22c67) Signed-off-by: Pavel Tikhomirov <ptikhomi...@virtuozzo.com> --- mm/memcontrol.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 8c14585f5e86..af99281292e5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -6674,6 +6674,14 @@ unsigned short mem_cgroup_id(struct mem_cgroup *memcg) return memcg->id.id; } +static void mem_cgroup_id_remove(struct mem_cgroup *memcg) +{ + if (memcg->id.id > 0) { + idr_remove(&mem_cgroup_idr, memcg->id.id); + memcg->id.id = 0; + } +} + static void mem_cgroup_id_get_many(struct mem_cgroup *memcg, unsigned int n) { atomic_add(n, &memcg->id.ref); @@ -6700,8 +6708,7 @@ static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg) static void mem_cgroup_id_put_many(struct mem_cgroup *memcg, unsigned int n) { if (atomic_sub_and_test(n, &memcg->id.ref)) { - idr_remove(&mem_cgroup_idr, memcg->id.id); - memcg->id.id = 0; + mem_cgroup_id_remove(memcg); /* Memcg ID pins CSS */ css_put(&memcg->css); @@ -6811,8 +6818,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) for_each_node(node) free_mem_cgroup_per_zone_info(memcg, node); - if (memcg->id.id > 0) - idr_remove(&mem_cgroup_idr, memcg->id.id); + mem_cgroup_id_remove(memcg); fail: kfree(memcg); return NULL; -- 2.40.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel