diff options
-rw-r--r-- | mm/memcontrol.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 085dc6d2f876..28928ce9b07f 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -292,6 +292,9 @@ struct mem_cgroup { | |||
292 | /* vmpressure notifications */ | 292 | /* vmpressure notifications */ |
293 | struct vmpressure vmpressure; | 293 | struct vmpressure vmpressure; |
294 | 294 | ||
295 | /* css_online() has been completed */ | ||
296 | int initialized; | ||
297 | |||
295 | /* | 298 | /* |
296 | * the counter to account for mem+swap usage. | 299 | * the counter to account for mem+swap usage. |
297 | */ | 300 | */ |
@@ -1099,10 +1102,21 @@ skip_node: | |||
1099 | * skipping css reference should be safe. | 1102 | * skipping css reference should be safe. |
1100 | */ | 1103 | */ |
1101 | if (next_css) { | 1104 | if (next_css) { |
1102 | if ((next_css == &root->css) || | 1105 | struct mem_cgroup *memcg = mem_cgroup_from_css(next_css); |
1103 | ((next_css->flags & CSS_ONLINE) && | 1106 | |
1104 | css_tryget_online(next_css))) | 1107 | if (next_css == &root->css) |
1105 | return mem_cgroup_from_css(next_css); | 1108 | return memcg; |
1109 | |||
1110 | if (css_tryget_online(next_css)) { | ||
1111 | /* | ||
1112 | * Make sure the memcg is initialized: | ||
1113 | * mem_cgroup_css_online() orders the the | ||
1114 | * initialization against setting the flag. | ||
1115 | */ | ||
1116 | if (smp_load_acquire(&memcg->initialized)) | ||
1117 | return memcg; | ||
1118 | css_put(next_css); | ||
1119 | } | ||
1106 | 1120 | ||
1107 | prev_css = next_css; | 1121 | prev_css = next_css; |
1108 | goto skip_node; | 1122 | goto skip_node; |
@@ -5549,6 +5563,7 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css) | |||
5549 | { | 5563 | { |
5550 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); | 5564 | struct mem_cgroup *memcg = mem_cgroup_from_css(css); |
5551 | struct mem_cgroup *parent = mem_cgroup_from_css(css->parent); | 5565 | struct mem_cgroup *parent = mem_cgroup_from_css(css->parent); |
5566 | int ret; | ||
5552 | 5567 | ||
5553 | if (css->id > MEM_CGROUP_ID_MAX) | 5568 | if (css->id > MEM_CGROUP_ID_MAX) |
5554 | return -ENOSPC; | 5569 | return -ENOSPC; |
@@ -5585,7 +5600,18 @@ mem_cgroup_css_online(struct cgroup_subsys_state *css) | |||
5585 | } | 5600 | } |
5586 | mutex_unlock(&memcg_create_mutex); | 5601 | mutex_unlock(&memcg_create_mutex); |
5587 | 5602 | ||
5588 | return memcg_init_kmem(memcg, &memory_cgrp_subsys); | 5603 | ret = memcg_init_kmem(memcg, &memory_cgrp_subsys); |
5604 | if (ret) | ||
5605 | return ret; | ||
5606 | |||
5607 | /* | ||
5608 | * Make sure the memcg is initialized: mem_cgroup_iter() | ||
5609 | * orders reading memcg->initialized against its callers | ||
5610 | * reading the memcg members. | ||
5611 | */ | ||
5612 | smp_store_release(&memcg->initialized, 1); | ||
5613 | |||
5614 | return 0; | ||
5589 | } | 5615 | } |
5590 | 5616 | ||
5591 | /* | 5617 | /* |