diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 62 |
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: | |||
6093 | static struct cgroup_subsys_state * __ref | 6093 | static struct cgroup_subsys_state * __ref |
6094 | mem_cgroup_css_alloc(struct cgroup *cont) | 6094 | mem_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 | |||
6135 | free_out: | ||
6136 | __mem_cgroup_free(memcg); | ||
6137 | return ERR_PTR(error); | ||
6138 | } | ||
6139 | |||
6140 | static int | ||
6141 | mem_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; |
6171 | free_out: | ||
6172 | __mem_cgroup_free(memcg); | ||
6173 | return ERR_PTR(error); | ||
6174 | } | 6191 | } |
6175 | 6192 | ||
6176 | static void mem_cgroup_css_offline(struct cgroup *cont) | 6193 | static 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, |