[Devel] [PATCH rh7 v4] mm/memcg: initialize mem_cgroup_per_zone_info earlier.

Andrey Ryabinin aryabinin at virtuozzo.com
Mon Mar 4 18:43:21 MSK 2019


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 <aryabinin at virtuozzo.com>
---
 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



More information about the Devel mailing list