[rh7,v3,5/7] mm/memcg: initialize mem_cgroup_per_zone_info earlier.

Submitted by Andrey Ryabinin on Feb. 27, 2019, 4:40 p.m.

Details

Message ID 20190227164005.26009-5-aryabinin@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Andrey Ryabinin Feb. 27, 2019, 4:40 p.m.
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@virtuozzo.com>
---
 mm/memcontrol.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 052b11501b8e..98cf7b56eaaa 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;