Add a selftest for the misc.mask cgroup interface. The test verifies that the misc.mask file is present and has the correct default value, that it is possible to write a new mask to the file, and that the mask is inherited by sub-cgroups. Signed-off-by: Andrei Vagin --- tools/testing/selftests/cgroup/.gitignore | 1 + tools/testing/selftests/cgroup/Makefile | 2 + tools/testing/selftests/cgroup/config | 1 + tools/testing/selftests/cgroup/test_misc.c | 118 +++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 tools/testing/selftests/cgroup/test_misc.c diff --git a/tools/testing/selftests/cgroup/.gitignore b/tools/testing/selftests/cgroup/.gitignore index 952e4448bf07..3ced02a3634b 100644 --- a/tools/testing/selftests/cgroup/.gitignore +++ b/tools/testing/selftests/cgroup/.gitignore @@ -7,6 +7,7 @@ test_hugetlb_memcg test_kill test_kmem test_memcontrol +test_misc test_pids test_zswap wait_inotify diff --git a/tools/testing/selftests/cgroup/Makefile b/tools/testing/selftests/cgroup/Makefile index e01584c2189a..6e9e92f89d8a 100644 --- a/tools/testing/selftests/cgroup/Makefile +++ b/tools/testing/selftests/cgroup/Makefile @@ -15,6 +15,7 @@ TEST_GEN_PROGS += test_hugetlb_memcg TEST_GEN_PROGS += test_kill TEST_GEN_PROGS += test_kmem TEST_GEN_PROGS += test_memcontrol +TEST_GEN_PROGS += test_misc TEST_GEN_PROGS += test_pids TEST_GEN_PROGS += test_zswap @@ -31,5 +32,6 @@ $(OUTPUT)/test_hugetlb_memcg: $(LIBCGROUP_O) $(OUTPUT)/test_kill: $(LIBCGROUP_O) $(OUTPUT)/test_kmem: $(LIBCGROUP_O) $(OUTPUT)/test_memcontrol: $(LIBCGROUP_O) +$(OUTPUT)/test_misc: $(LIBCGROUP_O) $(OUTPUT)/test_pids: $(LIBCGROUP_O) $(OUTPUT)/test_zswap: $(LIBCGROUP_O) diff --git a/tools/testing/selftests/cgroup/config b/tools/testing/selftests/cgroup/config index 39f979690dd3..9e3d03736f5a 100644 --- a/tools/testing/selftests/cgroup/config +++ b/tools/testing/selftests/cgroup/config @@ -1,6 +1,7 @@ CONFIG_CGROUPS=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_MISC=y CONFIG_CGROUP_SCHED=y CONFIG_MEMCG=y CONFIG_PAGE_COUNTER=y diff --git a/tools/testing/selftests/cgroup/test_misc.c b/tools/testing/selftests/cgroup/test_misc.c new file mode 100644 index 000000000000..50e8acb51852 --- /dev/null +++ b/tools/testing/selftests/cgroup/test_misc.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +#include "../kselftest.h" +#include "cgroup_util.h" + +/* + * This test checks that misc.mask works correctly. + */ +static int test_misc_mask(const char *root) +{ + int ret = KSFT_FAIL; + char *cg_misc, *cg_misc_sub = NULL; + + cg_misc = cg_name(root, "misc_test"); + if (!cg_misc) + goto cleanup; + + cg_misc_sub = cg_name(root, "misc_test/sub"); + if (!cg_misc_sub) + goto cleanup; + + if (cg_create(cg_misc)) + goto cleanup; + + if (cg_read_strcmp(cg_misc, "misc.mask", + "AT_HWCAP\t0x00000000000000\t0x00000000000000\n")) + goto cleanup; + + if (cg_write(cg_misc, "misc.mask", "AT_HWCAP 0xf0000000000000")) + goto cleanup; + + if (cg_read_strcmp(cg_misc, "misc.mask", + "AT_HWCAP\t0xf0000000000000\t0xf0000000000000\n")) + goto cleanup; + + if (cg_write(cg_misc, "cgroup.subtree_control", "+misc")) + goto cleanup; + + if (cg_create(cg_misc_sub)) + goto cleanup; + + if (cg_read_strcmp(cg_misc_sub, "misc.mask", + "AT_HWCAP\t0x00000000000000\t0xf0000000000000\n")) + goto cleanup; + + if (cg_write(cg_misc_sub, "misc.mask", "AT_HWCAP 0x01000000000000")) + goto cleanup; + + if (cg_read_strcmp(cg_misc_sub, "misc.mask", + "AT_HWCAP\t0x01000000000000\t0xf1000000000000\n")) + goto cleanup; + + ret = KSFT_PASS; + +cleanup: + cg_enter_current(root); + cg_destroy(cg_misc_sub); + cg_destroy(cg_misc); + free(cg_misc); + free(cg_misc_sub); + + return ret; +} + +#define T(x) { x, #x } +struct misc_test { + int (*fn)(const char *root); + const char *name; +} tests[] = { + T(test_misc_mask), +}; +#undef T + +int main(int argc, char **argv) +{ + char root[PATH_MAX]; + + ksft_print_header(); + ksft_set_plan(ARRAY_SIZE(tests)); + if (cg_find_unified_root(root, sizeof(root), NULL)) + ksft_exit_skip("cgroup v2 isn't mounted\n"); + + /* + * Check that misc controller is available: + * misc is listed in cgroup.controllers + */ + if (cg_read_strstr(root, "cgroup.controllers", "misc")) + ksft_exit_skip("misc controller isn't available\n"); + + if (cg_read_strstr(root, "cgroup.subtree_control", "misc")) + if (cg_write(root, "cgroup.subtree_control", "+misc")) + ksft_exit_skip("Failed to set misc controller\n"); + + for (int i = 0; i < ARRAY_SIZE(tests); i++) { + switch (tests[i].fn(root)) { + case KSFT_PASS: + ksft_test_result_pass("%s\n", tests[i].name); + break; + case KSFT_SKIP: + ksft_test_result_skip("%s\n", tests[i].name); + break; + default: + ksft_test_result_fail("%s\n", tests[i].name); + break; + } + } + + ksft_finished(); +} -- 2.52.0.223.gf5cc29aaa4-goog