aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a9318963d5d5..2bc3fbe93154 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4763,6 +4763,33 @@ static void mem_cgroup_reparent_charges(struct mem_cgroup *memcg)
4763} 4763}
4764 4764
4765/* 4765/*
4766 * This mainly exists for tests during the setting of set of use_hierarchy.
4767 * Since this is the very setting we are changing, the current hierarchy value
4768 * is meaningless
4769 */
4770static inline bool __memcg_has_children(struct mem_cgroup *memcg)
4771{
4772 struct cgroup *pos;
4773
4774 /* bounce at first found */
4775 cgroup_for_each_child(pos, memcg->css.cgroup)
4776 return true;
4777 return false;
4778}
4779
4780/*
4781 * Must be called with cgroup_lock held, unless the cgroup is guaranteed to be
4782 * already dead (in mem_cgroup_force_empty(), for instance). This is different
4783 * from mem_cgroup_count_children(), in the sense that we don't really care how
4784 * many children we have; we only need to know if we have any. It also counts
4785 * any memcg without hierarchy as infertile.
4786 */
4787static inline bool memcg_has_children(struct mem_cgroup *memcg)
4788{
4789 return memcg->use_hierarchy && __memcg_has_children(memcg);
4790}
4791
4792/*
4766 * Reclaims as many pages from the given memcg as possible and moves 4793 * Reclaims as many pages from the given memcg as possible and moves
4767 * the rest to the parent. 4794 * the rest to the parent.
4768 * 4795 *
@@ -4847,7 +4874,7 @@ static int mem_cgroup_hierarchy_write(struct cgroup *cont, struct cftype *cft,
4847 */ 4874 */
4848 if ((!parent_memcg || !parent_memcg->use_hierarchy) && 4875 if ((!parent_memcg || !parent_memcg->use_hierarchy) &&
4849 (val == 1 || val == 0)) { 4876 (val == 1 || val == 0)) {
4850 if (list_empty(&cont->children)) 4877 if (!__memcg_has_children(memcg))
4851 memcg->use_hierarchy = val; 4878 memcg->use_hierarchy = val;
4852 else 4879 else
4853 retval = -EBUSY; 4880 retval = -EBUSY;
@@ -4964,8 +4991,7 @@ static int memcg_update_kmem_limit(struct cgroup *cont, u64 val)
4964 cgroup_lock(); 4991 cgroup_lock();
4965 mutex_lock(&set_limit_mutex); 4992 mutex_lock(&set_limit_mutex);
4966 if (!memcg->kmem_account_flags && val != RESOURCE_MAX) { 4993 if (!memcg->kmem_account_flags && val != RESOURCE_MAX) {
4967 if (cgroup_task_count(cont) || (memcg->use_hierarchy && 4994 if (cgroup_task_count(cont) || memcg_has_children(memcg)) {
4968 !list_empty(&cont->children))) {
4969 ret = -EBUSY; 4995 ret = -EBUSY;
4970 goto out; 4996 goto out;
4971 } 4997 }
@@ -5373,8 +5399,7 @@ static int mem_cgroup_swappiness_write(struct cgroup *cgrp, struct cftype *cft,
5373 cgroup_lock(); 5399 cgroup_lock();
5374 5400
5375 /* If under hierarchy, only empty-root can set this value */ 5401 /* If under hierarchy, only empty-root can set this value */
5376 if ((parent->use_hierarchy) || 5402 if ((parent->use_hierarchy) || memcg_has_children(memcg)) {
5377 (memcg->use_hierarchy && !list_empty(&cgrp->children))) {
5378 cgroup_unlock(); 5403 cgroup_unlock();
5379 return -EINVAL; 5404 return -EINVAL;
5380 } 5405 }
@@ -5709,8 +5734,7 @@ static int mem_cgroup_oom_control_write(struct cgroup *cgrp,
5709 5734
5710 cgroup_lock(); 5735 cgroup_lock();
5711 /* oom-kill-disable is a flag for subhierarchy. */ 5736 /* oom-kill-disable is a flag for subhierarchy. */
5712 if ((parent->use_hierarchy) || 5737 if ((parent->use_hierarchy) || memcg_has_children(memcg)) {
5713 (memcg->use_hierarchy && !list_empty(&cgrp->children))) {
5714 cgroup_unlock(); 5738 cgroup_unlock();
5715 return -EINVAL; 5739 return -EINVAL;
5716 } 5740 }