aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorGlauber Costa <glommer@parallels.com>2013-02-22 19:34:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-23 20:50:18 -0500
commitd142e3e66731a0fb205a8158f5eec6f79a2ee478 (patch)
treeee6f541c79bfa5d00f5256303d54fa83f0dc2805 /mm/memcontrol.c
parentee5e8472b8df54fc00031d3b1089d5be50fb2ce0 (diff)
memcg: split part of memcg creation to css_online
This patch is a preparatory work for later locking rework to get rid of big cgroup lock from memory controller code. The memory controller uses some tunables to adjust its operation. Those tunables are inherited from parent to children upon children intialization. For most of them, the value cannot be changed after the parent has a new children. cgroup core splits initialization in two phases: css_alloc and css_online. After css_alloc, the memory allocation and basic initialization are done. But the new group is not yet visible anywhere, not even for cgroup core code. It is only somewhere between css_alloc and css_online that it is inserted into the internal children lists. Copying tunable values in css_alloc will lead to inconsistent values: the children will copy the old parent values, that can change between the copy and the moment in which the groups is linked to any data structure that can indicate the presence of children. Signed-off-by: Glauber Costa <glommer@parallels.com> Acked-by: Michal Hocko <mhocko@suse.cz> Cc: Tejun Heo <tj@kernel.org> Cc: Hiroyuki Kamezawa <kamezawa.hiroyuki@gmail.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c62
1 files changed, 40 insertions, 22 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 8e0988fee888..a9318963d5d5 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6093,7 +6093,7 @@ err_cleanup:
6093static struct cgroup_subsys_state * __ref 6093static struct cgroup_subsys_state * __ref
6094mem_cgroup_css_alloc(struct cgroup *cont) 6094mem_cgroup_css_alloc(struct cgroup *cont)
6095{ 6095{
6096 struct mem_cgroup *memcg, *parent; 6096 struct mem_cgroup *memcg;
6097 long error = -ENOMEM; 6097 long error = -ENOMEM;
6098 int node; 6098 int node;
6099 6099
@@ -6108,7 +6108,7 @@ mem_cgroup_css_alloc(struct cgroup *cont)
6108 /* root ? */ 6108 /* root ? */
6109 if (cont->parent == NULL) { 6109 if (cont->parent == NULL) {
6110 int cpu; 6110 int cpu;
6111 parent = NULL; 6111
6112 if (mem_cgroup_soft_limit_tree_init()) 6112 if (mem_cgroup_soft_limit_tree_init())
6113 goto free_out; 6113 goto free_out;
6114 root_mem_cgroup = memcg; 6114 root_mem_cgroup = memcg;
@@ -6117,13 +6117,43 @@ mem_cgroup_css_alloc(struct cgroup *cont)
6117 &per_cpu(memcg_stock, cpu); 6117 &per_cpu(memcg_stock, cpu);
6118 INIT_WORK(&stock->work, drain_local_stock); 6118 INIT_WORK(&stock->work, drain_local_stock);
6119 } 6119 }
6120 } else { 6120
6121 parent = mem_cgroup_from_cont(cont->parent); 6121 res_counter_init(&memcg->res, NULL);
6122 memcg->use_hierarchy = parent->use_hierarchy; 6122 res_counter_init(&memcg->memsw, NULL);
6123 memcg->oom_kill_disable = parent->oom_kill_disable; 6123 res_counter_init(&memcg->kmem, NULL);
6124 } 6124 }
6125 6125
6126 if (parent && parent->use_hierarchy) { 6126 memcg->last_scanned_node = MAX_NUMNODES;
6127 INIT_LIST_HEAD(&memcg->oom_notify);
6128 atomic_set(&memcg->refcnt, 1);
6129 memcg->move_charge_at_immigrate = 0;
6130 mutex_init(&memcg->thresholds_lock);
6131 spin_lock_init(&memcg->move_lock);
6132
6133 return &memcg->css;
6134
6135free_out:
6136 __mem_cgroup_free(memcg);
6137 return ERR_PTR(error);
6138}
6139
6140static int
6141mem_cgroup_css_online(struct cgroup *cont)
6142{
6143 struct mem_cgroup *memcg, *parent;
6144 int error = 0;
6145
6146 if (!cont->parent)
6147 return 0;
6148
6149 memcg = mem_cgroup_from_cont(cont);
6150 parent = mem_cgroup_from_cont(cont->parent);
6151
6152 memcg->use_hierarchy = parent->use_hierarchy;
6153 memcg->oom_kill_disable = parent->oom_kill_disable;
6154 memcg->swappiness = mem_cgroup_swappiness(parent);
6155
6156 if (parent->use_hierarchy) {
6127 res_counter_init(&memcg->res, &parent->res); 6157 res_counter_init(&memcg->res, &parent->res);
6128 res_counter_init(&memcg->memsw, &parent->memsw); 6158 res_counter_init(&memcg->memsw, &parent->memsw);
6129 res_counter_init(&memcg->kmem, &parent->kmem); 6159 res_counter_init(&memcg->kmem, &parent->kmem);
@@ -6144,18 +6174,9 @@ mem_cgroup_css_alloc(struct cgroup *cont)
6144 * much sense so let cgroup subsystem know about this 6174 * much sense so let cgroup subsystem know about this
6145 * unfortunate state in our controller. 6175 * unfortunate state in our controller.
6146 */ 6176 */
6147 if (parent && parent != root_mem_cgroup) 6177 if (parent != root_mem_cgroup)
6148 mem_cgroup_subsys.broken_hierarchy = true; 6178 mem_cgroup_subsys.broken_hierarchy = true;
6149 } 6179 }
6150 memcg->last_scanned_node = MAX_NUMNODES;
6151 INIT_LIST_HEAD(&memcg->oom_notify);
6152
6153 if (parent)
6154 memcg->swappiness = mem_cgroup_swappiness(parent);
6155 atomic_set(&memcg->refcnt, 1);
6156 memcg->move_charge_at_immigrate = 0;
6157 mutex_init(&memcg->thresholds_lock);
6158 spin_lock_init(&memcg->move_lock);
6159 6180
6160 error = memcg_init_kmem(memcg, &mem_cgroup_subsys); 6181 error = memcg_init_kmem(memcg, &mem_cgroup_subsys);
6161 if (error) { 6182 if (error) {
@@ -6165,12 +6186,8 @@ mem_cgroup_css_alloc(struct cgroup *cont)
6165 * call __mem_cgroup_free, so return directly 6186 * call __mem_cgroup_free, so return directly
6166 */ 6187 */
6167 mem_cgroup_put(memcg); 6188 mem_cgroup_put(memcg);
6168 return ERR_PTR(error);
6169 } 6189 }
6170 return &memcg->css; 6190 return error;
6171free_out:
6172 __mem_cgroup_free(memcg);
6173 return ERR_PTR(error);
6174} 6191}
6175 6192
6176static void mem_cgroup_css_offline(struct cgroup *cont) 6193static void mem_cgroup_css_offline(struct cgroup *cont)
@@ -6780,6 +6797,7 @@ struct cgroup_subsys mem_cgroup_subsys = {
6780 .name = "memory", 6797 .name = "memory",
6781 .subsys_id = mem_cgroup_subsys_id, 6798 .subsys_id = mem_cgroup_subsys_id,
6782 .css_alloc = mem_cgroup_css_alloc, 6799 .css_alloc = mem_cgroup_css_alloc,
6800 .css_online = mem_cgroup_css_online,
6783 .css_offline = mem_cgroup_css_offline, 6801 .css_offline = mem_cgroup_css_offline,
6784 .css_free = mem_cgroup_css_free, 6802 .css_free = mem_cgroup_css_free,
6785 .can_attach = mem_cgroup_can_attach, 6803 .can_attach = mem_cgroup_can_attach,