[LTP] [PATCH 2/2] controllers/memcg: Add cgroup2 support for regression tests

Luke Nowakowski-Krijger luke.nowakowskikrijger@canonical.com
Mon Nov 22 21:14:59 CET 2021


Add support for regression tests when memory controller is mounted on
cgroup2 hierarchy.

Most of the tests are still useful and require changing some parameters
to match the cgroup2 memory interface.

Signed-off-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>
---
 .../memcg/regression/memcg_regression_test.sh | 63 +++++++++++++++----
 .../memcg/regression/memcg_test_1.c           | 12 +++-
 .../memcg/regression/memcg_test_3.c           | 35 +++++------
 .../memcg/regression/memcg_test_4.sh          | 17 +++--
 4 files changed, 90 insertions(+), 37 deletions(-)

diff --git a/testcases/kernel/controllers/memcg/regression/memcg_regression_test.sh b/testcases/kernel/controllers/memcg/regression/memcg_regression_test.sh
index f7b9e7f81..417954613 100755
--- a/testcases/kernel/controllers/memcg/regression/memcg_regression_test.sh
+++ b/testcases/kernel/controllers/memcg/regression/memcg_regression_test.sh
@@ -80,6 +80,37 @@ check_kernel_bug()
 	return 0
 }
 
+setup_cgroupv2()
+{
+	cgroup_mount_point=$(grep -w cgroup2 /proc/mounts | cut -f 2 | cut -d " " -f2)
+	if ! grep -q memory "$cgroup_mount_point"/cgroup.controllers; then
+		tst_res TINFO "memory controller not supported on cgroup v2."
+		return
+	fi
+
+	ROD mkdir -p $mount_point
+	ROD mount -t cgroup2 none $mount_point
+
+	task_list="cgroup.procs"
+	memory_limit="memory.max"
+	cgroup_v="v2"
+}
+
+setup_cgroupv1()
+{
+	exist=$(grep -w memory /proc/cgroups | cut -f1);
+	if [ "$exist" = "" ]; then
+		tst_brk TCONF NULL "memory controller not supported"
+	fi
+
+	ROD mkdir -p $mount_point
+	ROD mount -t cgroup -o memory none $mount_point
+
+	task_list="tasks"
+	memory_limit="memory.limit_in_bytes"
+	cgroup_v="v1"
+}
+
 setup()
 {
 	mount_point="/dev/memcg"
@@ -89,13 +120,15 @@ setup()
 		tst_brk TBROK "Test should be run with kernel 2.6.30 or newer"
 	fi
 
-	exist=$(grep -w memory /proc/cgroups | cut -f1);
-	if [ "$exist" = "" ]; then
-		tst_brk TCONF "memory controller not supported"
+	if grep -q cgroup2 /proc/mounts; then
+		setup_cgroupv2
 	fi
 
-	ROD mkdir -p $mount_point
-	ROD mount -t cgroup -o memory none $mount_point
+	if [ -z "$cgroup_v" ]; then
+		setup_cgroupv1
+	fi
+
+	tst_res TINFO "test starts with cgroup $cgroup_v"
 }
 
 cleanup()
@@ -115,7 +148,7 @@ cleanup()
 test_1()
 {
 	ROD mkdir -p "$test_path"
-	ROD echo 0 > "$test_path"/memory.limit_in_bytes
+	ROD echo 0 > "$test_path/$memory_limit"
 
 	./memcg_test_1
 
@@ -136,6 +169,14 @@ test_1()
 #---------------------------------------------------------------------------
 test_2()
 {
+	# for cgroup2 writing to memory.max first checks the new limit against the
+	# current usage and will start killing processes if oom, therefore we do not
+	# expect EBUSY to be returned by the shrink operation.
+	if [ "$cgroup_v" = "v2" ]; then
+		tst_res TCONF "Cgroup v2 found, skipping test"
+		return
+	fi
+
 	./memcg_test_2 &
 	pid1=$!
 	sleep 1
@@ -188,12 +229,12 @@ test_2()
 test_3()
 {
 	ROD mkdir -p "$test_path"
-	for pid in $(cat "$mount_point"/tasks); do
-		echo $pid > "$test_path"/tasks 2> /dev/null
+	for pid in $(cat "$mount_point/$task_list"); do
+		echo $pid > "$test_path/$task_list" 2> /dev/null
 	done
 
-	for pid in $(cat "$test_path"/tasks); do
-		echo $pid > "$mount_point"/tasks 2> /dev/null
+	for pid in $(cat "$test_path/$task_list"); do
+		echo $pid > "$mount_point/$task_list" 2> /dev/null
 	done
 	rmdir "$test_path"
 
@@ -212,7 +253,7 @@ test_3()
 test_4()
 {
 	ROD mkdir -p "$test_path"
-	./memcg_test_4.sh
+	./memcg_test_4.sh "$cgroup_v"
 
 	check_kernel_bug
 	if [ $? -eq 1 ]; then
diff --git a/testcases/kernel/controllers/memcg/regression/memcg_test_1.c b/testcases/kernel/controllers/memcg/regression/memcg_test_1.c
index cb7e48c8c..9d1ed72f8 100644
--- a/testcases/kernel/controllers/memcg/regression/memcg_test_1.c
+++ b/testcases/kernel/controllers/memcg/regression/memcg_test_1.c
@@ -33,6 +33,16 @@
 
 #define FORKED_PROC_COUNT	10
 
+static int open_cgroup_tasklist(void)
+{
+	int fd = open("/dev/memcg/0/tasks", O_WRONLY);
+	if (fd >= 0)
+		return fd;
+
+	fd = open("/dev/memcg/0/cgroup.procs", O_WRONLY);
+	return fd;
+}
+
 int main(void)
 {
 	char buf[10];
@@ -40,7 +50,7 @@ int main(void)
 	int loop;
 	int pid;
 	int size = getpagesize();
-	int fd = open("/dev/memcg/0/tasks", O_WRONLY);
+	int fd = open_cgroup_tasklist();
 
 	if (fd < 0)
 		return 1;
diff --git a/testcases/kernel/controllers/memcg/regression/memcg_test_3.c b/testcases/kernel/controllers/memcg/regression/memcg_test_3.c
index 75a6e1545..9d9d24c73 100644
--- a/testcases/kernel/controllers/memcg/regression/memcg_test_3.c
+++ b/testcases/kernel/controllers/memcg/regression/memcg_test_3.c
@@ -17,12 +17,12 @@
 #include <sys/types.h>
 #include <sys/mount.h>
 #include "tst_test.h"
+#include "tst_cgroup.h"
 
-#define MNTPOINT	"memcg"
-#define SUBDIR	"memcg/testdir"
 
-static int mount_flag;
 static volatile int sigcounter;
+static const struct tst_cgroup_group *cg;
+static struct tst_cgroup_group *test_cg;
 
 static void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
 {
@@ -48,9 +48,10 @@ static void do_test(void)
 		do_child();
 
 	while (sigcounter < 50000) {
-		if (access(SUBDIR, F_OK))
-			SAFE_MKDIR(SUBDIR, 0644);
-		rmdir(SUBDIR);
+		test_cg = tst_cgroup_group_mk(cg, "test");
+
+		if (test_cg)
+			test_cg = tst_cgroup_group_rm(test_cg);
 	}
 
 	SAFE_KILL(cpid, SIGKILL);
@@ -61,32 +62,24 @@ static void do_test(void)
 
 static void setup(void)
 {
-	int ret;
-
-	SAFE_MKDIR(MNTPOINT, 0644);
+	tst_cgroup_require("memory", NULL);
 
-	ret = mount("memcg", MNTPOINT, "cgroup", 0, "memory");
-	if (ret) {
-		if (errno == ENOENT)
-			tst_brk(TCONF | TERRNO, "memcg not supported");
+	cg = tst_cgroup_get_test_group();
 
-		tst_brk(TCONF | TERRNO, "mounting memcg failed");
-	}
-	mount_flag = 1;
+	if (TST_CGROUP_VER(cg, "memory") != TST_CGROUP_V1)
+                SAFE_CGROUP_PRINT(cg, "cgroup.subtree_control", "+memory");
 }
 
 static void cleanup(void)
 {
-	if (!access(SUBDIR, F_OK))
-		SAFE_RMDIR(SUBDIR);
+	if (test_cg)
+		test_cg = tst_cgroup_group_rm(test_cg);
 
-	if (mount_flag)
-		tst_umount(MNTPOINT);
+	tst_cgroup_cleanup();
 }
 
 static struct tst_test test = {
 	.needs_root = 1,
-	.needs_tmpdir = 1,
 	.forks_child = 1,
 	.min_kver = "2.6.24",
 	.setup = setup,
diff --git a/testcases/kernel/controllers/memcg/regression/memcg_test_4.sh b/testcases/kernel/controllers/memcg/regression/memcg_test_4.sh
index 9115b1c27..10ea0972a 100755
--- a/testcases/kernel/controllers/memcg/regression/memcg_test_4.sh
+++ b/testcases/kernel/controllers/memcg/regression/memcg_test_4.sh
@@ -22,10 +22,19 @@
 ##                                                                            ##
 ################################################################################
 
+cgroup_v=$1
 mount_point="/dev/memcg"
 test_path="$mount_point"/0
 
-echo $$ > "$test_path"/tasks
+if [ $cgroup_v = "v2" ]; then
+	task_list="cgroup.procs"
+	memory_limit="memory.max"
+else
+	task_list="tasks"
+	memory_limit="memory.limit_in_bytes"
+fi
+
+echo $$ > "$test_path/$memory_limit"
 
 ./memcg_test_4 &
 pid=$!
@@ -36,13 +45,13 @@ sleep 1
 sleep 1
 
 # shrink memory, and then 80M will be swapped
-echo 40M > "$test_path"/memory.limit_in_bytes
+echo 40M > "$test_path/$memory_limit"
 
 # turn off swap, and swapoff will be killed
 swapoff -a
 sleep 1
-echo $pid > "$mount_point"/tasks 2> /dev/null
-echo $$ > "$mount_point"/tasks 2> /dev/null
+echo $pid > "$mount_point/$task_list" 2> /dev/null
+echo $$ > "$mount_point/$task_list"  2> /dev/null
 
 # now remove the cgroup
 rmdir "$test_path"
-- 
2.32.0



More information about the ltp mailing list