@@ -16,6 +16,9 @@ memcg_usage_in_bytes memcg_usage_in_bytes_test.sh
memcg_stress memcg_stress_test.sh
memcg_control memcg_control_test.sh
+# kselftest ports
+memcontrol01 memcontrol01
+
cgroup_fj_function_debug cgroup_fj_function.sh debug
cgroup_fj_function_cpuset cgroup_fj_function.sh cpuset
cgroup_fj_function_cpu cgroup_fj_function.sh cpu
@@ -5,3 +5,4 @@
/regression/memcg_test_3
/regression/memcg_test_4
/stress/memcg_process_stress
+memcontrol01
new file mode 100644
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+/*\
+ *
+ * [Description]
+ *
+ * Conversion of first kselftest in cgroup/test_memcontrol.c.
+ *
+ */
+#define _GNU_SOURCE
+
+#include <stdio.h>
+
+#include "tst_test.h"
+#include "tst_cgroup.h"
+
+static const struct tst_cgroup_group *cg_test;
+static struct tst_cgroup_group *parent, *child;
+static struct tst_cgroup_group *parent2, *child2;
+
+/*
+ * This test creates two nested cgroups with and without enabling
+ * the memory controller.
+ *
+ * The LTP API automatically adds controllers to subtree_control when
+ * a child cgroup is added. So unlike the kselftest we remove the
+ * controller again.
+ */
+static void test_memcg_subtree_control(void)
+{
+ parent = tst_cgroup_group_mk(cg_test, "memcg_test_0");
+ child = tst_cgroup_group_mk(parent, "memcg_test_1");
+ parent2 = tst_cgroup_group_mk(cg_test, "memcg_test_2");
+ child2 = tst_cgroup_group_mk(parent2, "memcg_test_3");
+
+ SAFE_CGROUP_PRINT(parent2, "cgroup.subtree_control", "-memory");
+
+ TST_EXP_POSITIVE(
+ SAFE_CGROUP_OCCURSIN(child, "cgroup.controllers", "memory"),
+ "child should have memory controller");
+ TST_EXP_POSITIVE(
+ !SAFE_CGROUP_OCCURSIN(child2, "cgroup.controllers", "memory"),
+ "child2 should not have memory controller");
+
+ child2 = tst_cgroup_group_rm(child2);
+ parent2 = tst_cgroup_group_rm(parent2);
+ child = tst_cgroup_group_rm(child);
+ parent = tst_cgroup_group_rm(parent);
+}
+
+static void setup(void)
+{
+ tst_cgroup_require("memory", NULL);
+ cg_test = tst_cgroup_get_test_group();
+
+ if (TST_CGROUP_VER(cg_test, "memory") == TST_CGROUP_V1)
+ tst_brk(TCONF, "V1 controllers do not have subtree control");
+}
+
+static void cleanup(void)
+{
+ if (child2)
+ child2 = tst_cgroup_group_rm(child2);
+ if (parent2)
+ parent2 = tst_cgroup_group_rm(parent2);
+ if (child)
+ child = tst_cgroup_group_rm(child);
+ if (parent)
+ parent = tst_cgroup_group_rm(parent);
+
+ tst_cgroup_cleanup();
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = test_memcg_subtree_control,
+};
This is a conversion of the first test in the memory cgroup kselftest. There will be a number of (more important) tests to follow; i.e. memcontrol02... Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com> --- runtest/controllers | 3 + testcases/kernel/controllers/memcg/.gitignore | 1 + .../kernel/controllers/memcg/memcontrol01.c | 77 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 testcases/kernel/controllers/memcg/memcontrol01.c