The commit is pushed to "branch-rh7-3.10.0-514.6.1.vz7.28.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-514.6.1.vz7.28.2 ------> commit 357f6ed81449fdc988771882f1f9b2e1c5455c04 Author: Andrey Ryabinin <aryabi...@virtuozzo.com> Date: Fri Jan 20 16:11:39 2017 +0400
ve/cgroups: Introduce subgroups_limit control Having a lot memory cgroups on machine may cause significant slowdown. So we want to limit number of sub-groups that container can create. This patch adds cgroup.subgroups_limit control file for that purpose. The file presents only on container's root cgroup. By default cgroup.subgroups_limit == 0 which means no limit. https://jira.sw.ru/browse/PSBM-33401 Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> Reviewed-by: Cyrill Gorcunov <gorcu...@openvz.org> --- include/linux/cgroup.h | 1 + kernel/cgroup.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 816cbac..d99251b 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -284,6 +284,7 @@ struct cgroup { /* directory xattrs */ struct simple_xattrs xattrs; + u64 subgroups_limit; }; #define MAX_CGROUP_ROOT_NAMELEN 64 diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 9a39c26..3e2de0b4 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -4040,6 +4040,19 @@ static int cgroup_clone_children_write(struct cgroup *cgrp, return 0; } +static u64 cgroup_read_subgroups_limit(struct cgroup *cgrp, + struct cftype *cft) +{ + return cgrp->subgroups_limit; +} +static int cgroup_write_subgroups_limit(struct cgroup *cgrp, + struct cftype *cft, + u64 val) +{ + cgrp->subgroups_limit = val; + return 0; +} + /* * for the common functions, 'private' gives the type of file */ @@ -4090,6 +4103,13 @@ static struct cftype files[] = { .write_string = cgroup_release_agent_write, .max_write_len = PATH_MAX, }, + { + .name = "cgroup.subgroups_limit", + .flags = CFTYPE_ONLY_ON_VE_ROOT, + .read_u64 = cgroup_read_subgroups_limit, + .write_u64 = cgroup_write_subgroups_limit, + .mode = S_IRUGO | S_IWUSR, + }, { } /* terminate */ }; @@ -4205,6 +4225,19 @@ static void offline_css(struct cgroup_subsys *ss, struct cgroup *cgrp) cgrp->subsys[ss->subsys_id]->flags &= ~CSS_ONLINE; } +static int subgroups_count(struct cgroup *cgroup) +{ + struct cgroup *pos; + int cgrps_count = 0; + + rcu_read_lock(); + cgroup_for_each_descendant_post(pos, cgroup) + cgrps_count++; + rcu_read_unlock(); + + return cgrps_count; +} + #ifdef CONFIG_VE static void cgroup_add_ve_root_files(struct cgroup *cgrp, struct cgroup_subsys *subsys, @@ -4244,6 +4277,27 @@ void cgroup_mark_ve_root(struct ve_struct *ve) mutex_unlock(&cgroup_mutex); } +static struct cgroup *cgroup_get_ve_root(struct cgroup *cgrp) +{ + struct cgroup *ve_root = NULL; + + rcu_read_lock(); + do { + if (test_bit(CGRP_VE_ROOT, &cgrp->flags)) { + ve_root = cgrp; + break; + } + cgrp = cgrp->parent; + } while (cgrp); + rcu_read_unlock(); + + return ve_root; +} +#else +static inline struct cgroup *cgroup_get_ve_root(struct cgroup *cgrp) +{ + return NULL; +} #endif /* @@ -4263,6 +4317,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, int err = 0; struct cgroup_subsys *ss; struct super_block *sb = root->sb; + struct cgroup *ve_root = parent; /* allocate the cgroup and its ID, 0 is reserved for the root */ cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); @@ -4278,6 +4333,13 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, if (cgrp->id < 0) goto err_free_name; + ve_root = cgroup_get_ve_root(parent); + if (ve_root && ve_root->subgroups_limit > 0 && + subgroups_count(ve_root) >= ve_root->subgroups_limit) { + err = -EACCES; + goto err_free_name; + } + /* * Only live parents can have children. Note that the liveliness * check isn't strictly necessary because cgroup_mkdir() and _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel