aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>2012-05-29 18:07:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-29 19:22:27 -0400
commitcc926f78420705817b807dbec0c5d3643827eba3 (patch)
treefea47aea4b5963fbf06e77c593abeee3afb1958b /mm/memcontrol.c
parentd01dd17f1067ca50dbb9d1d3400d33221ce339e7 (diff)
memcg: move charges to root cgroup if use_hierarchy=0
Presently, at removal of cgroup, ->pre_destroy() is called and moves charges to the parent cgroup. A major reason for returning -EBUSY from ->pre_destroy() is that the 'moving' hits the parent's resource limitation. It happens only when use_hierarchy=0. Considering use_hierarchy=0, all cgroups should be flat. So, no one cannot justify moving charges to parent...parent and children are in flat configuration, not hierarchical. This patch modifes the code to move charges to the root cgroup at rmdir/force_empty if use_hierarchy==0. This will much simplify rmdir() and reduce error in ->pre_destroy. Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Cc: Michal Hocko <mhocko@suse.cz> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ying Han <yinghan@google.com> Cc: Glauber Costa <glommer@parallels.com> Reviewed-by: Tejun Heo <tj@kernel.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.c34
1 files changed, 11 insertions, 23 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 1262a8bc402b..96cd9ebefb2c 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2678,15 +2678,13 @@ static int mem_cgroup_move_parent(struct page *page,
2678 struct mem_cgroup *child, 2678 struct mem_cgroup *child,
2679 gfp_t gfp_mask) 2679 gfp_t gfp_mask)
2680{ 2680{
2681 struct cgroup *cg = child->css.cgroup;
2682 struct cgroup *pcg = cg->parent;
2683 struct mem_cgroup *parent; 2681 struct mem_cgroup *parent;
2684 unsigned int nr_pages; 2682 unsigned int nr_pages;
2685 unsigned long uninitialized_var(flags); 2683 unsigned long uninitialized_var(flags);
2686 int ret; 2684 int ret;
2687 2685
2688 /* Is ROOT ? */ 2686 /* Is ROOT ? */
2689 if (!pcg) 2687 if (mem_cgroup_is_root(child))
2690 return -EINVAL; 2688 return -EINVAL;
2691 2689
2692 ret = -EBUSY; 2690 ret = -EBUSY;
@@ -2697,33 +2695,23 @@ static int mem_cgroup_move_parent(struct page *page,
2697 2695
2698 nr_pages = hpage_nr_pages(page); 2696 nr_pages = hpage_nr_pages(page);
2699 2697
2700 parent = mem_cgroup_from_cont(pcg); 2698 parent = parent_mem_cgroup(child);
2701 if (!parent->use_hierarchy) { 2699 /*
2702 ret = __mem_cgroup_try_charge(NULL, 2700 * If no parent, move charges to root cgroup.
2703 gfp_mask, nr_pages, &parent, false); 2701 */
2704 if (ret) 2702 if (!parent)
2705 goto put_back; 2703 parent = root_mem_cgroup;
2706 }
2707 2704
2708 if (nr_pages > 1) 2705 if (nr_pages > 1)
2709 flags = compound_lock_irqsave(page); 2706 flags = compound_lock_irqsave(page);
2710 2707
2711 if (parent->use_hierarchy) { 2708 ret = mem_cgroup_move_account(page, nr_pages,
2712 ret = mem_cgroup_move_account(page, nr_pages, 2709 pc, child, parent, false);
2713 pc, child, parent, false); 2710 if (!ret)
2714 if (!ret) 2711 __mem_cgroup_cancel_local_charge(child, nr_pages);
2715 __mem_cgroup_cancel_local_charge(child, nr_pages);
2716 } else {
2717 ret = mem_cgroup_move_account(page, nr_pages,
2718 pc, child, parent, true);
2719
2720 if (ret)
2721 __mem_cgroup_cancel_charge(parent, nr_pages);
2722 }
2723 2712
2724 if (nr_pages > 1) 2713 if (nr_pages > 1)
2725 compound_unlock_irqrestore(page, flags); 2714 compound_unlock_irqrestore(page, flags);
2726put_back:
2727 putback_lru_page(page); 2715 putback_lru_page(page);
2728put: 2716put:
2729 put_page(page); 2717 put_page(page);