[Devel] [PATCH rh9] cgroups: Replace own cgroup.subgroups_limit with mainstream cgroup.max.descendants

Konstantin Khorenko khorenko at virtuozzo.com
Tue Mar 21 20:52:49 MSK 2023


We have a feature of limiting the number of subcgroups, it is controlled
by the file cgroup.subgroups_limit and can be set for Container's top
cgroups only.

Mainstream has implemented similar functionality:
cgroup.max.descendants.
  1a926e0bbab8 ("cgroup: implement hierarchy limits")

So let's drop our implementation and use the mainstream one.

Notes:
  1. we'll keep old interface file cgroup.subgroups_limit for a while
     for backward compatibility, but it will be an alias to mainstream's
     cgroup.max.descendants.
  2. in mainstream cgroup.max.descendants is available for cgroup v2
     only, so make the patch makes it available for cgroup v1 as well.

Differences in behavior:
 * subgroups_limit could be set for Container's top cgroup only,
   max.descendants is available for configuration for any level cgroups

 * subgroups_limit default value was "0" which means "no limit".
   max.descendants default value is string "max" with the same meaning.

 * you can write "max" string to max.descendants file as a string unlike
   previous subgroups_limit.

Fixes: 34095bb615de ("ve/cgroups: Introduce subgroups_limit control")
https://jira.vzint.dev/browse/PSBM-144465

Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 include/linux/cgroup-defs.h     |  2 --
 kernel/cgroup/cgroup-internal.h |  4 ++++
 kernel/cgroup/cgroup-v1.c       | 25 +++++++------------------
 kernel/cgroup/cgroup.c          | 25 +++----------------------
 4 files changed, 14 insertions(+), 42 deletions(-)

diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
index a30c73cb61eb..fae0563f0436 100644
--- a/include/linux/cgroup-defs.h
+++ b/include/linux/cgroup-defs.h
@@ -501,8 +501,6 @@ struct cgroup {
 	/* Used to store internal freezer state */
 	struct cgroup_freezer_state freezer;
 
-	u64 subgroups_limit;
-
 	/* ve_owner, responsible for running release agent. */
 	struct ve_struct __rcu *ve_owner;
 
diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
index 197f680510ce..2aa4879d2d32 100644
--- a/kernel/cgroup/cgroup-internal.h
+++ b/kernel/cgroup/cgroup-internal.h
@@ -266,6 +266,10 @@ int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node,
 int __cgroup_task_count(const struct cgroup *cgrp);
 int cgroup_task_count(const struct cgroup *cgrp);
 
+int cgroup_max_descendants_show(struct seq_file *seq, void *v);
+ssize_t cgroup_max_descendants_write(struct kernfs_open_file *of,
+				     char *buf, size_t nbytes, loff_t off);
+
 /*
  * rstat.c
  */
diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c
index 15381e98df23..2bf2888e766f 100644
--- a/kernel/cgroup/cgroup-v1.c
+++ b/kernel/cgroup/cgroup-v1.c
@@ -664,22 +664,6 @@ static int cgroup_clone_children_write(struct cgroup_subsys_state *css,
 	return 0;
 }
 
-static u64 cgroup_read_subgroups_limit(struct cgroup_subsys_state *css,
-				       struct cftype *cft)
-{
-	return css->cgroup->subgroups_limit;
-}
-
-static int cgroup_write_subgroups_limit(struct cgroup_subsys_state *css,
-					struct cftype *cft, u64 val)
-{
-	if (!test_bit(CGRP_VE_ROOT, &css->cgroup->flags))
-		return -EACCES;
-
-	css->cgroup->subgroups_limit = val;
-	return 0;
-}
-
 /* cgroup core interface files for the legacy hierarchies */
 struct cftype cgroup1_base_files[] = {
 	{
@@ -726,8 +710,13 @@ struct cftype cgroup1_base_files[] = {
 	},
 	{
 		.name = "cgroup.subgroups_limit",
-		.read_u64 = cgroup_read_subgroups_limit,
-		.write_u64 = cgroup_write_subgroups_limit,
+		.seq_show = cgroup_max_descendants_show,
+		.write = cgroup_max_descendants_write,
+	},
+	{
+		.name = "cgroup.max.descendants",
+		.seq_show = cgroup_max_descendants_show,
+		.write = cgroup_max_descendants_write,
 	},
 	{ }	/* terminate */
 };
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index db9bf8fd3cd6..d401849adbe5 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -2311,18 +2311,6 @@ struct cgroup *cgroup_ve_root1(struct cgroup *cgrp)
 
 	return container_of(css, struct cgroup, self);
 }
-
-static bool subgroup_limit_reached(struct cgroup *cgroup)
-{
-	struct cgroup *ve_root;
-	bool ret = false;
-
-	ve_root = cgroup_ve_root1(cgroup);
-	if (ve_root && ve_root->subgroups_limit > 0 &&
-	    ve_root->nr_descendants >= ve_root->subgroups_limit)
-		ret = true;
-	return ret;
-}
 #endif /* CONFIG_VE */
 
 static void init_cgroup_housekeeping(struct cgroup *cgrp)
@@ -3855,7 +3843,7 @@ static ssize_t cgroup_type_write(struct kernfs_open_file *of, char *buf,
 	return ret ?: nbytes;
 }
 
-static int cgroup_max_descendants_show(struct seq_file *seq, void *v)
+int cgroup_max_descendants_show(struct seq_file *seq, void *v)
 {
 	struct cgroup *cgrp = seq_css(seq)->cgroup;
 	int descendants = READ_ONCE(cgrp->max_descendants);
@@ -3868,8 +3856,8 @@ static int cgroup_max_descendants_show(struct seq_file *seq, void *v)
 	return 0;
 }
 
-static ssize_t cgroup_max_descendants_write(struct kernfs_open_file *of,
-					   char *buf, size_t nbytes, loff_t off)
+ssize_t cgroup_max_descendants_write(struct kernfs_open_file *of,
+				     char *buf, size_t nbytes, loff_t off)
 {
 	struct cgroup *cgrp;
 	int descendants;
@@ -5910,13 +5898,6 @@ int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode)
 		goto out_unlock;
 	}
 
-#ifdef CONFIG_VE
-	if (!cgroup_on_dfl(cgrp) && subgroup_limit_reached(parent)) {
-		ret = -EACCES;
-		goto out_destroy;
-	}
-#endif
-
 	/*
 	 * This extra ref will be put in cgroup_free_fn() and guarantees
 	 * that @cgrp->kn is always accessible.
-- 
2.31.1



More information about the Devel mailing list