We are going to have the following piece of code.

memcg = mem_cgroup_from_id(memcgid)
lruvec = mem_cgroup_zone_lruvec(zone, memcg);

This currently cannot work because mem_cgroup_per_zone_info
allocated and initialized after memcgid become visible:

mem_cgroup_alloc():
        idr_replace(&mem_cgroup_idr, memcg, memcg->id);

Move per zone info initialization earlier, before idr_replace().
Same thing was done in upstream commit 0b8f73e1("mm: memcontrol: clean
 up alloc, online, offline, free functions") but I don't want
to do full backport, hence this patch.

https://jira.sw.ru/browse/PSBM-91933
Signed-off-by: Andrey Ryabinin <[email protected]>
---
 mm/memcontrol.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 052b11501b8e..88e6982c9e17 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6260,6 +6260,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
        size_t size;
        int id;
        int i, ret;
+       int node;
 
        size = sizeof(struct mem_cgroup);
        size += nr_node_ids * sizeof(struct mem_cgroup_per_node *);
@@ -6280,6 +6281,10 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
        if (!memcg->stat)
                goto out_free;
 
+       for_each_node(node)
+               if (alloc_mem_cgroup_per_zone_info(memcg, node))
+                       goto out_free;
+
        for (i = 0; i < MEM_CGROUP_STAT2_NSTATS; i++) {
                ret = percpu_counter_init(&memcg->stat2.counters[i], 0, 
GFP_KERNEL);
                if (ret)
@@ -6296,6 +6301,9 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
 
        free_percpu(memcg->stat);
 out_free:
+       for_each_node(node)
+               free_mem_cgroup_per_zone_info(memcg, node);
+
        if (memcg->id > 0) {
                idr_remove(&mem_cgroup_idr, memcg->id);
                synchronize_rcu();
@@ -6385,16 +6393,11 @@ mem_cgroup_css_alloc(struct cgroup *cont)
 {
        struct mem_cgroup *memcg;
        long error = -ENOMEM;
-       int node;
 
        memcg = mem_cgroup_alloc();
        if (!memcg)
                return ERR_PTR(error);
 
-       for_each_node(node)
-               if (alloc_mem_cgroup_per_zone_info(memcg, node))
-                       goto free_out;
-
        /* root ? */
        if (cont->parent == NULL) {
                root_mem_cgroup = memcg;
@@ -6420,10 +6423,6 @@ mem_cgroup_css_alloc(struct cgroup *cont)
 #endif
 
        return &memcg->css;
-
-free_out:
-       __mem_cgroup_free(memcg);
-       return ERR_PTR(error);
 }
 
 static int
-- 
2.19.2

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to