aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/memcontrol.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index f96ccc90fa6..e16694d5e11 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5247,16 +5247,29 @@ out_free:
5247} 5247}
5248 5248
5249/* 5249/*
5250 * Helpers for freeing a kmalloc()ed/vzalloc()ed mem_cgroup by RCU, 5250 * At destroying mem_cgroup, references from swap_cgroup can remain.
5251 * but in process context. The work_freeing structure is overlaid 5251 * (scanning all at force_empty is too costly...)
5252 * on the rcu_freeing structure, which itself is overlaid on memsw. 5252 *
5253 * Instead of clearing all references at force_empty, we remember
5254 * the number of reference from swap_cgroup and free mem_cgroup when
5255 * it goes down to 0.
5256 *
5257 * Removal of cgroup itself succeeds regardless of refs from swap.
5253 */ 5258 */
5254static void free_work(struct work_struct *work) 5259
5260static void __mem_cgroup_free(struct mem_cgroup *memcg)
5255{ 5261{
5256 struct mem_cgroup *memcg; 5262 int node;
5257 int size = sizeof(struct mem_cgroup); 5263 int size = sizeof(struct mem_cgroup);
5258 5264
5259 memcg = container_of(work, struct mem_cgroup, work_freeing); 5265 mem_cgroup_remove_from_trees(memcg);
5266 free_css_id(&mem_cgroup_subsys, &memcg->css);
5267
5268 for_each_node(node)
5269 free_mem_cgroup_per_zone_info(memcg, node);
5270
5271 free_percpu(memcg->stat);
5272
5260 /* 5273 /*
5261 * We need to make sure that (at least for now), the jump label 5274 * We need to make sure that (at least for now), the jump label
5262 * destruction code runs outside of the cgroup lock. This is because 5275 * destruction code runs outside of the cgroup lock. This is because
@@ -5275,38 +5288,27 @@ static void free_work(struct work_struct *work)
5275 vfree(memcg); 5288 vfree(memcg);
5276} 5289}
5277 5290
5278static void free_rcu(struct rcu_head *rcu_head)
5279{
5280 struct mem_cgroup *memcg;
5281
5282 memcg = container_of(rcu_head, struct mem_cgroup, rcu_freeing);
5283 INIT_WORK(&memcg->work_freeing, free_work);
5284 schedule_work(&memcg->work_freeing);
5285}
5286 5291
5287/* 5292/*
5288 * At destroying mem_cgroup, references from swap_cgroup can remain. 5293 * Helpers for freeing a kmalloc()ed/vzalloc()ed mem_cgroup by RCU,
5289 * (scanning all at force_empty is too costly...) 5294 * but in process context. The work_freeing structure is overlaid
5290 * 5295 * on the rcu_freeing structure, which itself is overlaid on memsw.
5291 * Instead of clearing all references at force_empty, we remember
5292 * the number of reference from swap_cgroup and free mem_cgroup when
5293 * it goes down to 0.
5294 *
5295 * Removal of cgroup itself succeeds regardless of refs from swap.
5296 */ 5296 */
5297 5297static void free_work(struct work_struct *work)
5298static void __mem_cgroup_free(struct mem_cgroup *memcg)
5299{ 5298{
5300 int node; 5299 struct mem_cgroup *memcg;
5301 5300
5302 mem_cgroup_remove_from_trees(memcg); 5301 memcg = container_of(work, struct mem_cgroup, work_freeing);
5303 free_css_id(&mem_cgroup_subsys, &memcg->css); 5302 __mem_cgroup_free(memcg);
5303}
5304 5304
5305 for_each_node(node) 5305static void free_rcu(struct rcu_head *rcu_head)
5306 free_mem_cgroup_per_zone_info(memcg, node); 5306{
5307 struct mem_cgroup *memcg;
5307 5308
5308 free_percpu(memcg->stat); 5309 memcg = container_of(rcu_head, struct mem_cgroup, rcu_freeing);
5309 call_rcu(&memcg->rcu_freeing, free_rcu); 5310 INIT_WORK(&memcg->work_freeing, free_work);
5311 schedule_work(&memcg->work_freeing);
5310} 5312}
5311 5313
5312static void mem_cgroup_get(struct mem_cgroup *memcg) 5314static void mem_cgroup_get(struct mem_cgroup *memcg)
@@ -5318,7 +5320,7 @@ static void __mem_cgroup_put(struct mem_cgroup *memcg, int count)
5318{ 5320{
5319 if (atomic_sub_and_test(count, &memcg->refcnt)) { 5321 if (atomic_sub_and_test(count, &memcg->refcnt)) {
5320 struct mem_cgroup *parent = parent_mem_cgroup(memcg); 5322 struct mem_cgroup *parent = parent_mem_cgroup(memcg);
5321 __mem_cgroup_free(memcg); 5323 call_rcu(&memcg->rcu_freeing, free_rcu);
5322 if (parent) 5324 if (parent)
5323 mem_cgroup_put(parent); 5325 mem_cgroup_put(parent);
5324 } 5326 }