diff options
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r-- | mm/memcontrol.c | 38 |
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 | */ | ||
4770 | static 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 | */ | ||
4787 | static 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 | } |