* [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API
@ 2022-01-27 6:12 Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 1/6] memcontrol02: Remove O_TMPFILE TCONF check Richard Palethorpe via ltp
` (5 more replies)
0 siblings, 6 replies; 11+ messages in thread
From: Richard Palethorpe via ltp @ 2022-01-27 6:12 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
Hello,
This adds a third test from the kselftests. Also I have finally taken
the step of moving the CGroup configuration to tst_test. This doesn't
save a huge amount of typing, but is good for the meta-data.
Richard Palethorpe (6):
memcontrol02: Remove O_TMPFILE TCONF check
API: Add tst_reap_child
memcontrol: Lift out some common definitions into a shared header
API/cgroup: Declare required controllers and version in test struct
API/cgroup: Add memory.min
memcontrol03: Copy from kselftest
include/tst_cgroup.h | 15 +-
include/tst_test.h | 23 ++
lib/newlib_tests/tst_cgroup01.c | 2 +-
lib/newlib_tests/tst_cgroup02.c | 2 +-
lib/tst_cgroup.c | 21 +-
lib/tst_test.c | 47 ++++
.../kernel/controllers/memcg/memcontrol01.c | 13 +-
.../kernel/controllers/memcg/memcontrol02.c | 50 +---
.../kernel/controllers/memcg/memcontrol03.c | 231 ++++++++++++++++++
.../controllers/memcg/memcontrol_common.h | 48 ++++
testcases/kernel/mem/cpuset/cpuset01.c | 4 +-
testcases/kernel/mem/ksm/ksm02.c | 4 +-
testcases/kernel/mem/ksm/ksm03.c | 4 +-
testcases/kernel/mem/ksm/ksm04.c | 7 +-
testcases/kernel/mem/oom/oom03.c | 4 +-
testcases/kernel/mem/oom/oom05.c | 8 +-
.../sched/cfs-scheduler/cfs_bandwidth01.c | 6 +-
testcases/kernel/syscalls/madvise/madvise06.c | 5 +-
18 files changed, 399 insertions(+), 95 deletions(-)
create mode 100644 testcases/kernel/controllers/memcg/memcontrol03.c
create mode 100644 testcases/kernel/controllers/memcg/memcontrol_common.h
--
2.34.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
* [LTP] [PATCH 1/6] memcontrol02: Remove O_TMPFILE TCONF check
2022-01-27 6:12 [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API Richard Palethorpe via ltp
@ 2022-01-27 6:12 ` Richard Palethorpe via ltp
2022-01-28 9:55 ` Cyril Hrubis
2022-01-27 6:12 ` [LTP] [PATCH 2/6] API: Add tst_reap_child Richard Palethorpe via ltp
` (4 subsequent siblings)
5 siblings, 1 reply; 11+ messages in thread
From: Richard Palethorpe via ltp @ 2022-01-27 6:12 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
We don't use O_TMPFILE anymore because the whole FS is temporary.
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
testcases/kernel/controllers/memcg/memcontrol02.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/testcases/kernel/controllers/memcg/memcontrol02.c b/testcases/kernel/controllers/memcg/memcontrol02.c
index 9fa4ff811..548f36829 100644
--- a/testcases/kernel/controllers/memcg/memcontrol02.c
+++ b/testcases/kernel/controllers/memcg/memcontrol02.c
@@ -94,16 +94,7 @@ static void alloc_pagecache_50M_check(void)
const char *const file_key_fmt =
TST_CGROUP_VER_IS_V1(cg_test, "memory") ? "cache %zd" : "file %zd";
- TEST(open(TMPDIR"/tmpfile", O_RDWR | O_CREAT, 0600));
-
- if (TST_RET < 0) {
- if (TST_ERR == EOPNOTSUPP)
- tst_brk(TCONF, "O_TMPFILE not supported by FS");
-
- tst_brk(TBROK | TTERRNO,
- "open(%s, O_TMPFILE | O_RDWR | O_EXCL", TMPDIR"/.");
- }
- fd = TST_RET;
+ fd = SAFE_OPEN(TMPDIR"/tmpfile", O_RDWR | O_CREAT, 0600);
SAFE_CGROUP_SCANF(cg_child, "memory.current", "%zu", ¤t);
tst_res(TINFO, "Created temp file: memory.current=%zu", current);
--
2.34.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH 2/6] API: Add tst_reap_child
2022-01-27 6:12 [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 1/6] memcontrol02: Remove O_TMPFILE TCONF check Richard Palethorpe via ltp
@ 2022-01-27 6:12 ` Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 3/6] memcontrol: Lift out some common definitions into a shared header Richard Palethorpe via ltp
` (3 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Richard Palethorpe via ltp @ 2022-01-27 6:12 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
Add a simple way to wait for a specific child process. This makes
sense when you want to wait for a child while others continue to run
in the background.
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
include/tst_test.h | 6 ++++++
lib/tst_test.c | 22 ++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/include/tst_test.h b/include/tst_test.h
index 450ddf086..8faf19141 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -106,6 +106,12 @@ pid_t safe_fork(const char *filename, unsigned int lineno);
*/
void tst_reap_children(void);
+/*
+ * Wait for one child and exit with TBROK if it returns a non-zero
+ * exit status
+ */
+void tst_reap_child(pid_t child);
+
struct tst_option {
char *optstr;
char **arg;
diff --git a/lib/tst_test.c b/lib/tst_test.c
index 844756fbd..156a1e4b3 100644
--- a/lib/tst_test.c
+++ b/lib/tst_test.c
@@ -416,6 +416,28 @@ void tst_reap_children(void)
}
}
+void tst_reap_child(const pid_t pid)
+{
+ int status;
+
+ for (;;) {
+ const pid_t ret_pid = waitpid(pid, &status, 0);
+
+ if (ret_pid > 0) {
+ check_child_status(ret_pid, status);
+ continue;
+ }
+
+ if (errno == ECHILD)
+ break;
+
+ if (errno == EINTR)
+ continue;
+
+ tst_brk(TBROK | TERRNO, "waitpid(%d, ...) failed", pid);
+ }
+}
+
pid_t safe_fork(const char *filename, unsigned int lineno)
{
--
2.34.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH 3/6] memcontrol: Lift out some common definitions into a shared header
2022-01-27 6:12 [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 1/6] memcontrol02: Remove O_TMPFILE TCONF check Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 2/6] API: Add tst_reap_child Richard Palethorpe via ltp
@ 2022-01-27 6:12 ` Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 4/6] API/cgroup: Declare required controllers and version in test struct Richard Palethorpe via ltp
` (2 subsequent siblings)
5 siblings, 0 replies; 11+ messages in thread
From: Richard Palethorpe via ltp @ 2022-01-27 6:12 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
Some simple functions can be shared between tests. The original
selftests share a bit more. However this doesn't make as much sense in
LTP due to library differences.
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
.../kernel/controllers/memcg/memcontrol02.c | 32 +------------
.../controllers/memcg/memcontrol_common.h | 48 +++++++++++++++++++
2 files changed, 49 insertions(+), 31 deletions(-)
create mode 100644 testcases/kernel/controllers/memcg/memcontrol_common.h
diff --git a/testcases/kernel/controllers/memcg/memcontrol02.c b/testcases/kernel/controllers/memcg/memcontrol02.c
index 548f36829..d5a24cc0a 100644
--- a/testcases/kernel/controllers/memcg/memcontrol02.c
+++ b/testcases/kernel/controllers/memcg/memcontrol02.c
@@ -23,14 +23,7 @@
*/
#define _GNU_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "tst_test.h"
-#include "tst_cgroup.h"
-
-#define TMPDIR "mntdir"
-#define MB(x) (x << 20)
+#include "memcontrol_common.h"
static size_t page_size;
static const struct tst_cgroup_group *cg_test;
@@ -38,20 +31,6 @@ static struct tst_cgroup_group *cg_child;
static int fd;
static int file_to_all_error = 10;
-/*
- * Checks if two given values differ by less than err% of their
- * sum. An extra percent is added for every doubling of the page size
- * to compensate for wastage in page sized allocations.
- */
-static inline int values_close(const ssize_t a,
- const ssize_t b,
- const ssize_t err)
-{
- const ssize_t page_adjusted_err = ffs(page_size >> 13) + err;
-
- return 100 * labs(a - b) <= (a + b) * page_adjusted_err;
-}
-
static void alloc_anon_50M_check(void)
{
const ssize_t size = MB(50);
@@ -78,15 +57,6 @@ static void alloc_anon_50M_check(void)
current, anon);
}
-static void alloc_pagecache(const int fd, size_t size)
-{
- char buf[BUFSIZ];
- size_t i;
-
- for (i = 0; i < size; i += sizeof(buf))
- SAFE_WRITE(1, fd, buf, sizeof(buf));
-}
-
static void alloc_pagecache_50M_check(void)
{
const size_t size = MB(50);
diff --git a/testcases/kernel/controllers/memcg/memcontrol_common.h b/testcases/kernel/controllers/memcg/memcontrol_common.h
new file mode 100644
index 000000000..67f3ca318
--- /dev/null
+++ b/testcases/kernel/controllers/memcg/memcontrol_common.h
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "tst_test.h"
+#include "tst_cgroup.h"
+
+#define TMPDIR "mntdir"
+#define MB(x) (x << 20)
+
+/*
+ * Checks if two given values differ by less than err% of their
+ * sum. An extra percent is added for every doubling of the page size
+ * to compensate for wastage in page sized allocations.
+ */
+static inline int values_close(const ssize_t a,
+ const ssize_t b,
+ const ssize_t err)
+{
+ const size_t page_size = SAFE_SYSCONF(_SC_PAGESIZE);
+ const ssize_t page_adjusted_err = ffs(page_size >> 13) + err;
+
+ return 100 * labs(a - b) <= (a + b) * page_adjusted_err;
+}
+
+static inline void alloc_pagecache(const int fd, size_t size)
+{
+ char buf[BUFSIZ];
+ size_t i;
+
+ SAFE_LSEEK(fd, 0, SEEK_END);
+
+ for (i = 0; i < size; i += sizeof(buf))
+ SAFE_WRITE(1, fd, buf, sizeof(buf));
+}
+
+static inline void alloc_anon(const size_t size)
+{
+ const size_t page_size = SAFE_SYSCONF(_SC_PAGESIZE);
+ char *const buf = SAFE_MALLOC(size);
+ size_t i;
+
+ for (i = 0; i < size; i += page_size)
+ buf[i] = 0;
+
+ free(buf);
+}
--
2.34.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH 4/6] API/cgroup: Declare required controllers and version in test struct
2022-01-27 6:12 [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API Richard Palethorpe via ltp
` (2 preceding siblings ...)
2022-01-27 6:12 ` [LTP] [PATCH 3/6] memcontrol: Lift out some common definitions into a shared header Richard Palethorpe via ltp
@ 2022-01-27 6:12 ` Richard Palethorpe via ltp
2022-01-28 10:01 ` Cyril Hrubis
2022-01-27 6:12 ` [LTP] [PATCH 5/6] API/cgroup: Add memory.min Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest Richard Palethorpe via ltp
5 siblings, 1 reply; 11+ messages in thread
From: Richard Palethorpe via ltp @ 2022-01-27 6:12 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
This allows the test author to declaratively specify the required
CGroup controllers in struct tst_test. Also they can optionally
specify the CGroup API version. In some cases this removes any need for a
setup function. It also adds CGroup information to the meta-data.
In theory its possible to require that only one controller is on a
particular version while others are free to be on any. Currently this
would still need to be handled by calling tst_cgroup_require() and
checking the controller version. So far we do not have any tests which
need to be run in such a hybrid scenario. Usually if V2 and V1 are
mounted at once, V2 is empty. So this does not complicate the
declaration by allowing the version to be specified on a per
controller basis.
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
include/tst_cgroup.h | 15 +++--------
include/tst_test.h | 17 +++++++++++++
lib/newlib_tests/tst_cgroup01.c | 2 +-
lib/newlib_tests/tst_cgroup02.c | 2 +-
lib/tst_cgroup.c | 18 ++++++++++---
lib/tst_test.c | 25 +++++++++++++++++++
.../kernel/controllers/memcg/memcontrol01.c | 13 +++-------
.../kernel/controllers/memcg/memcontrol02.c | 7 ++----
testcases/kernel/mem/cpuset/cpuset01.c | 4 +--
testcases/kernel/mem/ksm/ksm02.c | 4 +--
testcases/kernel/mem/ksm/ksm03.c | 4 +--
testcases/kernel/mem/ksm/ksm04.c | 7 +++---
testcases/kernel/mem/oom/oom03.c | 4 +--
testcases/kernel/mem/oom/oom05.c | 8 +++---
.../sched/cfs-scheduler/cfs_bandwidth01.c | 6 ++---
testcases/kernel/syscalls/madvise/madvise06.c | 5 ++--
16 files changed, 88 insertions(+), 53 deletions(-)
diff --git a/include/tst_cgroup.h b/include/tst_cgroup.h
index 5190d8794..9b5c49e44 100644
--- a/include/tst_cgroup.h
+++ b/include/tst_cgroup.h
@@ -83,21 +83,14 @@
#include <sys/types.h>
-/* CGroups Kernel API version */
-enum tst_cgroup_ver {
- TST_CGROUP_V1 = 1,
- TST_CGROUP_V2 = 2,
-};
-
/* Used to specify CGroup hierarchy configuration options, allowing a
* test to request a particular CGroup structure.
*/
struct tst_cgroup_opts {
- /* Only try to mount V1 CGroup controllers. This will not
- * prevent V2 from being used if it is already mounted, it
- * only indicates that we should mount V1 controllers if
- * nothing is present. By default we try to mount V2 first. */
- int only_mount_v1:1;
+ /* Call tst_brk with TCONF if the controller is not on this
+ * version. Defautls to zero to accept any version.
+ */
+ enum tst_cgroup_ver needs_ver;
};
/* A Control Group in LTP's aggregated hierarchy */
diff --git a/include/tst_test.h b/include/tst_test.h
index 8faf19141..7c863db07 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -139,6 +139,14 @@ extern unsigned int tst_variant;
#define TST_NO_HUGEPAGES ((unsigned long)-1)
+/* CGroups Kernel API version */
+enum tst_cgroup_ver {
+ TST_CGROUP_V1 = 1,
+ TST_CGROUP_V2 = 2,
+};
+
+struct tst_cgroup_group;
+
struct tst_test {
/* number of tests available in test() function */
unsigned int tcnt;
@@ -286,6 +294,15 @@ struct tst_test {
/* NULL terminated array of required commands */
const char *const *needs_cmds;
+
+ /* Requires a particular CGroup API version. */
+ const enum tst_cgroup_ver needs_cgroup_ver;
+
+ /* {} terminated array of required CGroup controllers */
+ const char *const *needs_cgroup_controllers;
+
+ /* Populated with a reference to this tests's CGroup */
+ const struct tst_cgroup_group **const test_cgroup;
};
/*
diff --git a/lib/newlib_tests/tst_cgroup01.c b/lib/newlib_tests/tst_cgroup01.c
index 54a370362..62df9aab2 100644
--- a/lib/newlib_tests/tst_cgroup01.c
+++ b/lib/newlib_tests/tst_cgroup01.c
@@ -22,7 +22,7 @@ static void do_test(void)
static void setup(void)
{
- cgopts.only_mount_v1 = !!only_mount_v1,
+ cgopts.needs_ver = !!only_mount_v1 ? TST_CGROUP_V1 : 0;
tst_cgroup_scan();
tst_cgroup_print_config();
diff --git a/lib/newlib_tests/tst_cgroup02.c b/lib/newlib_tests/tst_cgroup02.c
index 64b0a1e94..988282f14 100644
--- a/lib/newlib_tests/tst_cgroup02.c
+++ b/lib/newlib_tests/tst_cgroup02.c
@@ -59,7 +59,7 @@ static void do_test(void)
static void setup(void)
{
- cgopts.only_mount_v1 = !!only_mount_v1,
+ cgopts.needs_ver = !!only_mount_v1 ? TST_CGROUP_V1 : 0;
tst_cgroup_scan();
tst_cgroup_print_config();
diff --git a/lib/tst_cgroup.c b/lib/tst_cgroup.c
index 10b65364b..2c63dca54 100644
--- a/lib/tst_cgroup.c
+++ b/lib/tst_cgroup.c
@@ -196,7 +196,7 @@ static struct cgroup_ctrl controllers[] = {
{ }
};
-static const struct tst_cgroup_opts default_opts = { 0 };
+static const struct tst_cgroup_opts default_opts;
/* We should probably allow these to be set in environment
* variables
@@ -623,13 +623,14 @@ void tst_cgroup_require(const char *const ctrl_name,
if (ctrl->ctrl_root)
goto mkdirs;
- if (!cgroup_v2_mounted() && !options->only_mount_v1)
+ if (!cgroup_v2_mounted() && options->needs_ver != TST_CGROUP_V1)
cgroup_mount_v2();
if (ctrl->ctrl_root)
goto mkdirs;
- cgroup_mount_v1(ctrl);
+ if (options->needs_ver != TST_CGROUP_V2)
+ cgroup_mount_v1(ctrl);
if (!ctrl->ctrl_root) {
tst_brk(TCONF,
@@ -642,6 +643,17 @@ mkdirs:
root = ctrl->ctrl_root;
add_ctrl(&root->mnt_dir.ctrl_field, ctrl);
+ if (cgroup_ctrl_on_v2(ctrl) && options->needs_ver == TST_CGROUP_V1) {
+ tst_brk(TCONF,
+ "V1 '%s' controller required, but it's mounted on V2",
+ ctrl->ctrl_name);
+ }
+ if (!cgroup_ctrl_on_v2(ctrl) && options->needs_ver == TST_CGROUP_V2) {
+ tst_brk(TCONF,
+ "V2 '%s' controller required, but it's mounted on V1",
+ ctrl->ctrl_name);
+ }
+
if (cgroup_ctrl_on_v2(ctrl)) {
if (root->we_mounted_it) {
SAFE_FILE_PRINTFAT(root->mnt_dir.dir_fd,
diff --git a/lib/tst_test.c b/lib/tst_test.c
index 156a1e4b3..bdab524f6 100644
--- a/lib/tst_test.c
+++ b/lib/tst_test.c
@@ -30,6 +30,7 @@
#include "tst_sys_conf.h"
#include "tst_kconfig.h"
#include "tst_private.h"
+#include "tst_cgroup.h"
#include "old_resource.h"
#include "old_device.h"
#include "old_tmpdir.h"
@@ -1035,6 +1036,20 @@ static void prepare_device(void)
}
}
+static void do_cgroup_requires(void)
+{
+ const struct tst_cgroup_opts cg_opts = {
+ .needs_ver = tst_test->needs_cgroup_ver,
+ };
+ const char *const *ctrl_names = tst_test->needs_cgroup_controllers;
+
+ for (; *ctrl_names; ctrl_names++)
+ tst_cgroup_require(*ctrl_names, &cg_opts);
+
+ if (tst_test->test_cgroup)
+ *(tst_test->test_cgroup) = tst_cgroup_get_test_group();
+}
+
static void do_setup(int argc, char *argv[])
{
if (!tst_test)
@@ -1187,6 +1202,13 @@ static void do_setup(int argc, char *argv[])
if (tst_test->taint_check)
tst_taint_init(tst_test->taint_check);
+
+ if (tst_test->needs_cgroup_controllers)
+ do_cgroup_requires();
+ else if (tst_test->needs_cgroup_ver)
+ tst_brk(TBROK, "needs_cgroup_ver only works with needs_cgroup_controllers");
+ else if (tst_test->test_cgroup)
+ tst_brk(TBROK, "test_cgroup only works with needs_cgroup_controllers");
}
static void do_test_setup(void)
@@ -1220,6 +1242,9 @@ static void do_test_setup(void)
static void do_cleanup(void)
{
+ if (tst_test->needs_cgroup_controllers)
+ tst_cgroup_cleanup();
+
if (ovl_mounted)
SAFE_UMOUNT(OVL_MNT);
diff --git a/testcases/kernel/controllers/memcg/memcontrol01.c b/testcases/kernel/controllers/memcg/memcontrol01.c
index f3b45610e..84a1634ee 100644
--- a/testcases/kernel/controllers/memcg/memcontrol01.c
+++ b/testcases/kernel/controllers/memcg/memcontrol01.c
@@ -44,15 +44,6 @@ static void test_memcg_subtree_control(void)
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_IS_V1(cg_test, "memory"))
- tst_brk(TCONF, "V1 controllers do not have subtree control");
-}
-
static void cleanup(void)
{
if (child2)
@@ -68,7 +59,9 @@ static void cleanup(void)
}
static struct tst_test test = {
- .setup = setup,
.cleanup = cleanup,
.test_all = test_memcg_subtree_control,
+ .needs_cgroup_ver = TST_CGROUP_V2,
+ .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
+ .test_cgroup = &cg_test,
};
diff --git a/testcases/kernel/controllers/memcg/memcontrol02.c b/testcases/kernel/controllers/memcg/memcontrol02.c
index d5a24cc0a..6f7bc7a4c 100644
--- a/testcases/kernel/controllers/memcg/memcontrol02.c
+++ b/testcases/kernel/controllers/memcg/memcontrol02.c
@@ -114,9 +114,6 @@ static void setup(void)
{
page_size = SAFE_SYSCONF(_SC_PAGESIZE);
- tst_cgroup_require("memory", NULL);
- cg_test = tst_cgroup_get_test_group();
-
switch (tst_fs_type(TMPDIR)) {
case TST_VFAT_MAGIC:
case TST_EXFAT_MAGIC:
@@ -130,8 +127,6 @@ static void cleanup(void)
{
if (cg_child)
cg_child = tst_cgroup_group_rm(cg_child);
-
- tst_cgroup_cleanup();
}
static struct tst_test test = {
@@ -145,4 +140,6 @@ static struct tst_test test = {
.all_filesystems = 1,
.forks_child = 1,
.needs_root = 1,
+ .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
+ .test_cgroup = &cg_test,
};
diff --git a/testcases/kernel/mem/cpuset/cpuset01.c b/testcases/kernel/mem/cpuset/cpuset01.c
index 66c18f6ab..272a38bd5 100644
--- a/testcases/kernel/mem/cpuset/cpuset01.c
+++ b/testcases/kernel/mem/cpuset/cpuset01.c
@@ -80,14 +80,12 @@ static void test_cpuset(void)
static void setup(void)
{
- tst_cgroup_require("cpuset", NULL);
ncpus = count_cpu();
if (get_allowed_nodes_arr(NH_MEMS | NH_CPUS, &nnodes, &nodes) < 0)
tst_brk(TBROK | TERRNO, "get_allowed_nodes_arr");
if (nnodes <= 1)
tst_brk(TCONF, "requires a NUMA system.");
- cg = tst_cgroup_get_test_group();
SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
}
@@ -186,6 +184,8 @@ static struct tst_test test = {
.cleanup = cleanup,
.test_all = test_cpuset,
.min_kver = "2.6.32",
+ .needs_cgroup_controllers = (const char *const []){ "cpuset", NULL },
+ .test_cgroup = &cg,
};
#else
diff --git a/testcases/kernel/mem/ksm/ksm02.c b/testcases/kernel/mem/ksm/ksm02.c
index c578cfb7f..7afa5ee12 100644
--- a/testcases/kernel/mem/ksm/ksm02.c
+++ b/testcases/kernel/mem/ksm/ksm02.c
@@ -107,8 +107,6 @@ static void setup(void)
SAFE_FILE_PRINTF(PATH_KSM "merge_across_nodes", "1");
}
- tst_cgroup_require("cpuset", NULL);
- cg = tst_cgroup_get_test_group();
cg_drain = tst_cgroup_get_drain_group();
}
@@ -129,6 +127,8 @@ static struct tst_test test = {
},
.test_all = verify_ksm,
.min_kver = "2.6.32",
+ .needs_cgroup_controllers = (const char *const []){ "cpuset", NULL },
+ .test_cgroup = &cg,
};
#else
diff --git a/testcases/kernel/mem/ksm/ksm03.c b/testcases/kernel/mem/ksm/ksm03.c
index df847cf95..01a908b01 100644
--- a/testcases/kernel/mem/ksm/ksm03.c
+++ b/testcases/kernel/mem/ksm/ksm03.c
@@ -79,8 +79,6 @@ static void setup(void)
parse_ksm_options(opt_sizestr, &size, opt_numstr, &num, opt_unitstr, &unit);
- tst_cgroup_require("memory", NULL);
- cg = tst_cgroup_get_test_group();
SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
SAFE_CGROUP_PRINTF(cg, "memory.max", "%lu", TESTMEM);
}
@@ -110,4 +108,6 @@ static struct tst_test test = {
},
.test_all = verify_ksm,
.min_kver = "2.6.32",
+ .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
+ .test_cgroup = &cg,
};
diff --git a/testcases/kernel/mem/ksm/ksm04.c b/testcases/kernel/mem/ksm/ksm04.c
index e8bc1de85..0941fcc10 100644
--- a/testcases/kernel/mem/ksm/ksm04.c
+++ b/testcases/kernel/mem/ksm/ksm04.c
@@ -106,9 +106,6 @@ static void setup(void)
parse_ksm_options(opt_sizestr, &size, opt_numstr, &num, opt_unitstr, &unit);
- tst_cgroup_require("memory", NULL);
- tst_cgroup_require("cpuset", NULL);
- cg = tst_cgroup_get_test_group();
SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
}
@@ -129,6 +126,10 @@ static struct tst_test test = {
},
.test_all = verify_ksm,
.min_kver = "2.6.32",
+ .needs_cgroup_controllers = (const char *const []){
+ "memory", "cpuset", NULL
+ },
+ .test_cgroup = &cg,
};
#else
diff --git a/testcases/kernel/mem/oom/oom03.c b/testcases/kernel/mem/oom/oom03.c
index 451119166..952c0d031 100644
--- a/testcases/kernel/mem/oom/oom03.c
+++ b/testcases/kernel/mem/oom/oom03.c
@@ -84,8 +84,6 @@ static void setup(void)
overcommit = get_sys_tune("overcommit_memory");
set_sys_tune("overcommit_memory", 1, 1);
- tst_cgroup_require("memory", NULL);
- cg = tst_cgroup_get_test_group();
SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
SAFE_CGROUP_PRINTF(cg, "memory.max", "%lu", TESTMEM);
}
@@ -104,6 +102,8 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.test_all = verify_oom,
+ .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
+ .test_cgroup = &cg,
};
#else
diff --git a/testcases/kernel/mem/oom/oom05.c b/testcases/kernel/mem/oom/oom05.c
index 06497261e..ab2ad788b 100644
--- a/testcases/kernel/mem/oom/oom05.c
+++ b/testcases/kernel/mem/oom/oom05.c
@@ -90,10 +90,6 @@ void setup(void)
overcommit = get_sys_tune("overcommit_memory");
set_sys_tune("overcommit_memory", 1, 1);
- tst_cgroup_require("memory", NULL);
- tst_cgroup_require("cpuset", NULL);
- cg = tst_cgroup_get_test_group();
-
/*
* Some nodes do not contain memory, so use
* get_allowed_nodes(NH_MEMS) to get a memory
@@ -124,6 +120,10 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.test_all = verify_oom,
+ .needs_cgroup_controllers = (const char *const []){
+ "memory", "cpuset", NULL
+ },
+ .test_cgroup = &cg,
};
#else
diff --git a/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c b/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
index e3eb237da..0c3146fb3 100644
--- a/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
+++ b/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
@@ -132,10 +132,6 @@ static void do_test(void)
static void setup(void)
{
- tst_cgroup_require("cpu", NULL);
-
- cg_test = tst_cgroup_get_test_group();
-
cg_level2 = tst_cgroup_group_mk(cg_test, "level2");
cg_level3a = tst_cgroup_group_mk(cg_level2, "level3a");
@@ -182,6 +178,8 @@ static struct tst_test test = {
"CONFIG_CFS_BANDWIDTH",
NULL
},
+ .needs_cgroup_controllers = (const char *const []){"cpu", NULL},
+ .test_cgroup = &cg_test,
.tags = (const struct tst_tag[]) {
{"linux-git", "39f23ce07b93"},
{"linux-git", "b34cb07dde7c"},
diff --git a/testcases/kernel/syscalls/madvise/madvise06.c b/testcases/kernel/syscalls/madvise/madvise06.c
index 263b8e78b..4d8b6575d 100644
--- a/testcases/kernel/syscalls/madvise/madvise06.c
+++ b/testcases/kernel/syscalls/madvise/madvise06.c
@@ -121,9 +121,6 @@ static void setup(void)
check_path("/proc/self/oom_score_adj");
SAFE_FILE_PRINTF("/proc/self/oom_score_adj", "%d", -1000);
- tst_cgroup_require("memory", NULL);
- cg = tst_cgroup_get_test_group();
-
SAFE_CGROUP_PRINTF(cg, "memory.max", "%ld", MEM_LIMIT);
if (SAFE_CGROUP_HAS(cg, "memory.swap.max"))
SAFE_CGROUP_PRINTF(cg, "memory.swap.max", "%ld", MEMSW_LIMIT);
@@ -245,6 +242,8 @@ static struct tst_test test = {
"?/proc/sys/vm/swappiness",
NULL
},
+ .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
+ .test_cgroup = &cg,
.tags = (const struct tst_tag[]) {
{"linux-git", "55231e5c898c"},
{"linux-git", "8de15e920dc8"},
--
2.34.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH 5/6] API/cgroup: Add memory.min
2022-01-27 6:12 [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API Richard Palethorpe via ltp
` (3 preceding siblings ...)
2022-01-27 6:12 ` [LTP] [PATCH 4/6] API/cgroup: Declare required controllers and version in test struct Richard Palethorpe via ltp
@ 2022-01-27 6:12 ` Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest Richard Palethorpe via ltp
5 siblings, 0 replies; 11+ messages in thread
From: Richard Palethorpe via ltp @ 2022-01-27 6:12 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
lib/tst_cgroup.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/tst_cgroup.c b/lib/tst_cgroup.c
index 2c63dca54..784f629d8 100644
--- a/lib/tst_cgroup.c
+++ b/lib/tst_cgroup.c
@@ -152,6 +152,7 @@ static const struct cgroup_file cgroup_ctrl_files[] = {
static const struct cgroup_file memory_ctrl_files[] = {
{ "memory.current", "memory.usage_in_bytes", CTRL_MEMORY },
+ { "memory.min", NULL, CTRL_MEMORY },
{ "memory.max", "memory.limit_in_bytes", CTRL_MEMORY },
{ "memory.stat", "memory.stat", CTRL_MEMORY },
{ "memory.swappiness", "memory.swappiness", CTRL_MEMORY },
@@ -888,7 +889,7 @@ tst_cgroup_group_mk(const struct tst_cgroup_group *const parent,
for_each_dir(parent, 0, dir) {
new_dir = SAFE_MALLOC(sizeof(*new_dir));
- cgroup_dir_mk(*dir, group_name, new_dir);
+ cgroup_dir_mk(*dir, cg->group_name, new_dir);
cgroup_group_add_dir(parent, cg, new_dir);
}
--
2.34.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest
2022-01-27 6:12 [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API Richard Palethorpe via ltp
` (4 preceding siblings ...)
2022-01-27 6:12 ` [LTP] [PATCH 5/6] API/cgroup: Add memory.min Richard Palethorpe via ltp
@ 2022-01-27 6:12 ` Richard Palethorpe via ltp
2022-01-27 8:26 ` Richard Palethorpe
2022-01-28 10:57 ` Cyril Hrubis
5 siblings, 2 replies; 11+ messages in thread
From: Richard Palethorpe via ltp @ 2022-01-27 6:12 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
Note that the tolerances had to be increased slightly otherwise the
test only passed on ext4 in upstream 5.16 on x86_64. In all cases it
seems more memory is evicted from C than expected and not enough from
D. This may indicate some tuning is possible, but does not look like a
serious regression.
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
.../kernel/controllers/memcg/memcontrol03.c | 231 ++++++++++++++++++
1 file changed, 231 insertions(+)
create mode 100644 testcases/kernel/controllers/memcg/memcontrol03.c
diff --git a/testcases/kernel/controllers/memcg/memcontrol03.c b/testcases/kernel/controllers/memcg/memcontrol03.c
new file mode 100644
index 000000000..4d6ca9761
--- /dev/null
+++ b/testcases/kernel/controllers/memcg/memcontrol03.c
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0
+/*\
+ *
+ * [Description]
+ *
+ * Conversion of the third kself test in cgroup/test_memcontrol.c.
+ *
+ * Original description:
+ * "First, this test creates the following hierarchy:
+ * A memory.min = 50M, memory.max = 200M
+ * A/B memory.min = 50M, memory.current = 50M
+ * A/B/C memory.min = 75M, memory.current = 50M
+ * A/B/D memory.min = 25M, memory.current = 50M
+ * A/B/E memory.min = 500M, memory.current = 0
+ * A/B/F memory.min = 0, memory.current = 50M
+ *
+ * Usages are pagecache, but the test keeps a running
+ * process in every leaf cgroup.
+ * Then it creates A/G and creates a significant
+ * memory pressure in it.
+ *
+ * A/B memory.current ~= 50M
+ * A/B/C memory.current ~= 33M
+ * A/B/D memory.current ~= 17M
+ * A/B/E memory.current ~= 0
+ *
+ * After that it tries to allocate more than there is unprotected
+ * memory in A available, and checks that memory.min protects
+ * pagecache even in this case."
+ *
+ * memory.min doesn't appear to exist on V1 so we only test on V2 like
+ * the selftest. We do test on more file systems, but not tempfs
+ * becaue it can't evict the page cache without swap. Also we avoid
+ * filesystems which allocate extra memory for buffer heads.
+ *
+ * The tolerances have been increased from the self tests.
+ *
+ */
+
+#define _GNU_SOURCE
+
+#include <inttypes.h>
+
+#include "memcontrol_common.h"
+
+#define TMPDIR "mntdir"
+
+static const struct tst_cgroup_group *cg_test;
+static struct tst_cgroup_group *parent[3];
+static struct tst_cgroup_group *children[4];
+static int fd;
+
+enum checkpoints {
+ CHILD_IDLE,
+ TEST_DONE,
+};
+
+static void cleanup_sub_groups(void)
+{
+ size_t i;
+
+ for (i = ARRAY_SIZE(children); i > 0; i--) {
+ if (!children[i - 1])
+ continue;
+
+ TST_CHECKPOINT_WAKE2(TEST_DONE,
+ ARRAY_SIZE(children) - 1);
+ tst_reap_children();
+ break;
+ }
+
+ for (i = ARRAY_SIZE(children); i > 0; i--) {
+ if (!children[i - 1])
+ continue;
+
+ children[i - 1] = tst_cgroup_group_rm(children[i - 1]);
+ }
+
+ for (i = ARRAY_SIZE(parent); i > 0; i--) {
+ if (!parent[i - 1])
+ continue;
+
+ parent[i - 1] = tst_cgroup_group_rm(parent[i - 1]);
+ }
+}
+
+static void alloc_anon_in_child(const struct tst_cgroup_group *const cg,
+ const size_t size, const int expect_oom)
+{
+ int status;
+ const pid_t pid = SAFE_FORK();
+
+ if (!pid) {
+ SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
+
+ tst_res(TINFO, "%d in %s: Allocating anon: %"PRIdPTR,
+ getpid(), tst_cgroup_group_name(cg), size);
+ alloc_anon(size);
+ exit(0);
+ }
+
+ if (expect_oom)
+ SAFE_WAITPID(pid, &status, 0);
+ else
+ tst_reap_child(pid);
+}
+
+static void alloc_pagecache_in_child(const struct tst_cgroup_group *const cg,
+ const size_t size)
+{
+ const pid_t pid = SAFE_FORK();
+
+ if (pid) {
+ TST_CHECKPOINT_WAIT(CHILD_IDLE);
+ return;
+ }
+
+ SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
+
+ tst_res(TINFO, "%d in %s: Allocating pagecache: %"PRIdPTR,
+ getpid(), tst_cgroup_group_name(cg), size);
+ alloc_pagecache(fd, size);
+
+ TST_CHECKPOINT_WAKE(CHILD_IDLE);
+ TST_CHECKPOINT_WAIT(TEST_DONE);
+ exit(0);
+}
+
+/*
+ */
+static void test_memcg_min(void)
+{
+ long c[4];
+ size_t i, attempts;
+ char child_name[64];
+
+ fd = SAFE_OPEN(TMPDIR"/tmpfile", O_RDWR | O_CREAT, 0600);
+ parent[0] = tst_cgroup_group_mk(cg_test, "memcg_test_0");
+
+ SAFE_CGROUP_SCANF(parent[0], "memory.min", "%ld", c);
+ if (c[0]) {
+ tst_brk(TCONF,
+ "memory.min already set to %ld on parent group", c[0]);
+ }
+
+ if (!TST_CGROUP_VER_IS_V1(parent[0], "memory")) {
+ SAFE_CGROUP_PRINT(parent[0], "cgroup.subtree_control",
+ "+memory");
+ }
+ SAFE_CGROUP_PRINT(parent[0], "memory.max", "200M");
+ SAFE_CGROUP_PRINT(parent[0], "memory.swap.max", "0");
+
+ parent[1] = tst_cgroup_group_mk(parent[0], "memcg_test_1");
+ if (!TST_CGROUP_VER_IS_V1(parent[0], "memory")) {
+ SAFE_CGROUP_PRINT(parent[1], "cgroup.subtree_control",
+ "+memory");
+ }
+
+ parent[2] = tst_cgroup_group_mk(parent[0], "memcg_test_2");
+
+ for (i = 0; i < ARRAY_SIZE(children); i++) {
+ sprintf(child_name, "child_memcg_%"PRIdPTR, i);
+
+ children[i] = tst_cgroup_group_mk(parent[1], child_name);
+
+ if (i == 2)
+ continue;
+
+ alloc_pagecache_in_child(children[i], MB(50));
+ }
+
+ SAFE_CGROUP_PRINT(parent[0], "memory.min", "50M");
+ SAFE_CGROUP_PRINT(parent[1], "memory.min", "50M");
+ SAFE_CGROUP_PRINT(children[0], "memory.min", "75M");
+ SAFE_CGROUP_PRINT(children[1], "memory.min", "25M");
+ SAFE_CGROUP_PRINT(children[2], "memory.min", "500M");
+ SAFE_CGROUP_PRINT(children[3], "memory.min", "0");
+
+ for (attempts = 0; attempts < 5; attempts++) {
+ SAFE_CGROUP_SCANF(parent[1], "memory.current", "%ld", c);
+ if (values_close(c[0], MB(150), 3))
+ break;
+
+ sleep(1);
+ }
+
+ alloc_anon_in_child(parent[2], MB(148), 0);
+
+ SAFE_CGROUP_SCANF(parent[1], "memory.current", "%ld", c);
+ TST_EXP_EXPR(values_close(c[0], MB(50), 5), "(A/B memory.current=%ld) ~= %d", c[0], MB(50));
+
+ for (i = 0; i < ARRAY_SIZE(children); i++)
+ SAFE_CGROUP_SCANF(children[i], "memory.current", "%ld", c + i);
+
+ TST_EXP_EXPR(values_close(c[0], MB(33), 20), "(A/B/C memory.current=%ld) ~= %d", c[0], MB(33));
+ TST_EXP_EXPR(values_close(c[1], MB(17), 20), "(A/B/D memory.current=%ld) ~= %d", c[1], MB(17));
+ TST_EXP_EXPR(values_close(c[2], 0, 1), "(A/B/E memory.current=%ld) ~= 0", c[2]);
+
+ alloc_anon_in_child(parent[2], MB(170), 1);
+
+ SAFE_CGROUP_SCANF(parent[1], "memory.current", "%ld", c);
+ TST_EXP_EXPR(values_close(c[0], MB(50), 5), "(A/B memory.current=%ld) ~= %d", c[0], MB(50));
+
+ cleanup_sub_groups();
+ SAFE_CLOSE(fd);
+}
+
+static void cleanup(void)
+{
+ cleanup_sub_groups();
+ if (fd > -1)
+ SAFE_CLOSE(fd);
+}
+
+static struct tst_test test = {
+ .cleanup = cleanup,
+ .test_all = test_memcg_min,
+ .mount_device = 1,
+ .dev_min_size = 256,
+ .mntpoint = TMPDIR,
+ .all_filesystems = 1,
+ .skip_filesystems = (const char *const[]){
+ "exfat", "vfat", "fuse", "ntfs", "tmpfs", NULL
+ },
+ .forks_child = 1,
+ .needs_root = 1,
+ .needs_checkpoints = 1,
+ .needs_cgroup_ver = TST_CGROUP_V2,
+ .needs_cgroup_controllers = (const char *const[]){ "memory", NULL },
+ .test_cgroup = &cg_test,
+};
--
2.34.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest
2022-01-27 6:12 ` [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest Richard Palethorpe via ltp
@ 2022-01-27 8:26 ` Richard Palethorpe
2022-01-28 10:57 ` Cyril Hrubis
1 sibling, 0 replies; 11+ messages in thread
From: Richard Palethorpe @ 2022-01-27 8:26 UTC (permalink / raw)
To: ltp; +Cc: Richard Palethorpe
Hello,
Richard Palethorpe <rpalethorpe@suse.com> writes:
> Note that the tolerances had to be increased slightly otherwise the
> test only passed on ext4 in upstream 5.16 on x86_64. In all cases it
> seems more memory is evicted from C than expected and not enough from
> D. This may indicate some tuning is possible, but does not look like a
> serious regression.
>
> Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
> ---
> .../kernel/controllers/memcg/memcontrol03.c | 231 ++++++++++++++++++
> 1 file changed, 231 insertions(+)
> create mode 100644 testcases/kernel/controllers/memcg/memcontrol03.c
Oops, I forgot to add the gitignore and runtest entries!
--
Thank you,
Richard.
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [LTP] [PATCH 1/6] memcontrol02: Remove O_TMPFILE TCONF check
2022-01-27 6:12 ` [LTP] [PATCH 1/6] memcontrol02: Remove O_TMPFILE TCONF check Richard Palethorpe via ltp
@ 2022-01-28 9:55 ` Cyril Hrubis
0 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2022-01-28 9:55 UTC (permalink / raw)
To: Richard Palethorpe; +Cc: ltp
Hi!
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [LTP] [PATCH 4/6] API/cgroup: Declare required controllers and version in test struct
2022-01-27 6:12 ` [LTP] [PATCH 4/6] API/cgroup: Declare required controllers and version in test struct Richard Palethorpe via ltp
@ 2022-01-28 10:01 ` Cyril Hrubis
0 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2022-01-28 10:01 UTC (permalink / raw)
To: Richard Palethorpe; +Cc: ltp
Hi!
> /* A Control Group in LTP's aggregated hierarchy */
> diff --git a/include/tst_test.h b/include/tst_test.h
> index 8faf19141..7c863db07 100644
> --- a/include/tst_test.h
> +++ b/include/tst_test.h
> @@ -139,6 +139,14 @@ extern unsigned int tst_variant;
>
> #define TST_NO_HUGEPAGES ((unsigned long)-1)
>
> +/* CGroups Kernel API version */
> +enum tst_cgroup_ver {
> + TST_CGROUP_V1 = 1,
> + TST_CGROUP_V2 = 2,
> +};
> +
> +struct tst_cgroup_group;
> +
> struct tst_test {
> /* number of tests available in test() function */
> unsigned int tcnt;
> @@ -286,6 +294,15 @@ struct tst_test {
>
> /* NULL terminated array of required commands */
> const char *const *needs_cmds;
> +
> + /* Requires a particular CGroup API version. */
> + const enum tst_cgroup_ver needs_cgroup_ver;
> +
> + /* {} terminated array of required CGroup controllers */
> + const char *const *needs_cgroup_controllers;
> +
> + /* Populated with a reference to this tests's CGroup */
> + const struct tst_cgroup_group **const test_cgroup;
The usuall approach is not to pullute the tst_test structure with
pointer to the actuall allocated resources. We just put the description
of what is required for the test and the put the initialized structure
into a global variable such as tst_dev.
So in this case I would just decleare extern struct tst_cgroup_group
*tst_cgroup in tst_cgroup.h which would be declared in the tst_cgroup.c
and initialized with the right pointer when cgroups were requested in
the tst_test structure.
> };
>
> /*
> diff --git a/lib/newlib_tests/tst_cgroup01.c b/lib/newlib_tests/tst_cgroup01.c
> index 54a370362..62df9aab2 100644
> --- a/lib/newlib_tests/tst_cgroup01.c
> +++ b/lib/newlib_tests/tst_cgroup01.c
> @@ -22,7 +22,7 @@ static void do_test(void)
>
> static void setup(void)
> {
> - cgopts.only_mount_v1 = !!only_mount_v1,
> + cgopts.needs_ver = !!only_mount_v1 ? TST_CGROUP_V1 : 0;
>
> tst_cgroup_scan();
> tst_cgroup_print_config();
> diff --git a/lib/newlib_tests/tst_cgroup02.c b/lib/newlib_tests/tst_cgroup02.c
> index 64b0a1e94..988282f14 100644
> --- a/lib/newlib_tests/tst_cgroup02.c
> +++ b/lib/newlib_tests/tst_cgroup02.c
> @@ -59,7 +59,7 @@ static void do_test(void)
>
> static void setup(void)
> {
> - cgopts.only_mount_v1 = !!only_mount_v1,
> + cgopts.needs_ver = !!only_mount_v1 ? TST_CGROUP_V1 : 0;
>
> tst_cgroup_scan();
> tst_cgroup_print_config();
> diff --git a/lib/tst_cgroup.c b/lib/tst_cgroup.c
> index 10b65364b..2c63dca54 100644
> --- a/lib/tst_cgroup.c
> +++ b/lib/tst_cgroup.c
> @@ -196,7 +196,7 @@ static struct cgroup_ctrl controllers[] = {
> { }
> };
>
> -static const struct tst_cgroup_opts default_opts = { 0 };
> +static const struct tst_cgroup_opts default_opts;
>
> /* We should probably allow these to be set in environment
> * variables
> @@ -623,13 +623,14 @@ void tst_cgroup_require(const char *const ctrl_name,
> if (ctrl->ctrl_root)
> goto mkdirs;
>
> - if (!cgroup_v2_mounted() && !options->only_mount_v1)
> + if (!cgroup_v2_mounted() && options->needs_ver != TST_CGROUP_V1)
> cgroup_mount_v2();
>
> if (ctrl->ctrl_root)
> goto mkdirs;
>
> - cgroup_mount_v1(ctrl);
> + if (options->needs_ver != TST_CGROUP_V2)
> + cgroup_mount_v1(ctrl);
>
> if (!ctrl->ctrl_root) {
> tst_brk(TCONF,
> @@ -642,6 +643,17 @@ mkdirs:
> root = ctrl->ctrl_root;
> add_ctrl(&root->mnt_dir.ctrl_field, ctrl);
>
> + if (cgroup_ctrl_on_v2(ctrl) && options->needs_ver == TST_CGROUP_V1) {
> + tst_brk(TCONF,
> + "V1 '%s' controller required, but it's mounted on V2",
> + ctrl->ctrl_name);
> + }
> + if (!cgroup_ctrl_on_v2(ctrl) && options->needs_ver == TST_CGROUP_V2) {
> + tst_brk(TCONF,
> + "V2 '%s' controller required, but it's mounted on V1",
> + ctrl->ctrl_name);
> + }
> +
> if (cgroup_ctrl_on_v2(ctrl)) {
> if (root->we_mounted_it) {
> SAFE_FILE_PRINTFAT(root->mnt_dir.dir_fd,
> diff --git a/lib/tst_test.c b/lib/tst_test.c
> index 156a1e4b3..bdab524f6 100644
> --- a/lib/tst_test.c
> +++ b/lib/tst_test.c
> @@ -30,6 +30,7 @@
> #include "tst_sys_conf.h"
> #include "tst_kconfig.h"
> #include "tst_private.h"
> +#include "tst_cgroup.h"
> #include "old_resource.h"
> #include "old_device.h"
> #include "old_tmpdir.h"
> @@ -1035,6 +1036,20 @@ static void prepare_device(void)
> }
> }
>
> +static void do_cgroup_requires(void)
> +{
> + const struct tst_cgroup_opts cg_opts = {
> + .needs_ver = tst_test->needs_cgroup_ver,
> + };
> + const char *const *ctrl_names = tst_test->needs_cgroup_controllers;
> +
> + for (; *ctrl_names; ctrl_names++)
> + tst_cgroup_require(*ctrl_names, &cg_opts);
> +
> + if (tst_test->test_cgroup)
> + *(tst_test->test_cgroup) = tst_cgroup_get_test_group();
> +}
> +
> static void do_setup(int argc, char *argv[])
> {
> if (!tst_test)
> @@ -1187,6 +1202,13 @@ static void do_setup(int argc, char *argv[])
>
> if (tst_test->taint_check)
> tst_taint_init(tst_test->taint_check);
> +
> + if (tst_test->needs_cgroup_controllers)
> + do_cgroup_requires();
> + else if (tst_test->needs_cgroup_ver)
> + tst_brk(TBROK, "needs_cgroup_ver only works with needs_cgroup_controllers");
> + else if (tst_test->test_cgroup)
> + tst_brk(TBROK, "test_cgroup only works with needs_cgroup_controllers");
> }
>
> static void do_test_setup(void)
> @@ -1220,6 +1242,9 @@ static void do_test_setup(void)
>
> static void do_cleanup(void)
> {
> + if (tst_test->needs_cgroup_controllers)
> + tst_cgroup_cleanup();
> +
> if (ovl_mounted)
> SAFE_UMOUNT(OVL_MNT);
>
> diff --git a/testcases/kernel/controllers/memcg/memcontrol01.c b/testcases/kernel/controllers/memcg/memcontrol01.c
> index f3b45610e..84a1634ee 100644
> --- a/testcases/kernel/controllers/memcg/memcontrol01.c
> +++ b/testcases/kernel/controllers/memcg/memcontrol01.c
> @@ -44,15 +44,6 @@ static void test_memcg_subtree_control(void)
> 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_IS_V1(cg_test, "memory"))
> - tst_brk(TCONF, "V1 controllers do not have subtree control");
> -}
> -
> static void cleanup(void)
> {
> if (child2)
> @@ -68,7 +59,9 @@ static void cleanup(void)
> }
>
> static struct tst_test test = {
> - .setup = setup,
> .cleanup = cleanup,
> .test_all = test_memcg_subtree_control,
> + .needs_cgroup_ver = TST_CGROUP_V2,
> + .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
> + .test_cgroup = &cg_test,
> };
> diff --git a/testcases/kernel/controllers/memcg/memcontrol02.c b/testcases/kernel/controllers/memcg/memcontrol02.c
> index d5a24cc0a..6f7bc7a4c 100644
> --- a/testcases/kernel/controllers/memcg/memcontrol02.c
> +++ b/testcases/kernel/controllers/memcg/memcontrol02.c
> @@ -114,9 +114,6 @@ static void setup(void)
> {
> page_size = SAFE_SYSCONF(_SC_PAGESIZE);
>
> - tst_cgroup_require("memory", NULL);
> - cg_test = tst_cgroup_get_test_group();
> -
> switch (tst_fs_type(TMPDIR)) {
> case TST_VFAT_MAGIC:
> case TST_EXFAT_MAGIC:
> @@ -130,8 +127,6 @@ static void cleanup(void)
> {
> if (cg_child)
> cg_child = tst_cgroup_group_rm(cg_child);
> -
> - tst_cgroup_cleanup();
> }
>
> static struct tst_test test = {
> @@ -145,4 +140,6 @@ static struct tst_test test = {
> .all_filesystems = 1,
> .forks_child = 1,
> .needs_root = 1,
> + .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
> + .test_cgroup = &cg_test,
> };
> diff --git a/testcases/kernel/mem/cpuset/cpuset01.c b/testcases/kernel/mem/cpuset/cpuset01.c
> index 66c18f6ab..272a38bd5 100644
> --- a/testcases/kernel/mem/cpuset/cpuset01.c
> +++ b/testcases/kernel/mem/cpuset/cpuset01.c
> @@ -80,14 +80,12 @@ static void test_cpuset(void)
>
> static void setup(void)
> {
> - tst_cgroup_require("cpuset", NULL);
> ncpus = count_cpu();
> if (get_allowed_nodes_arr(NH_MEMS | NH_CPUS, &nnodes, &nodes) < 0)
> tst_brk(TBROK | TERRNO, "get_allowed_nodes_arr");
> if (nnodes <= 1)
> tst_brk(TCONF, "requires a NUMA system.");
>
> - cg = tst_cgroup_get_test_group();
> SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
> }
>
> @@ -186,6 +184,8 @@ static struct tst_test test = {
> .cleanup = cleanup,
> .test_all = test_cpuset,
> .min_kver = "2.6.32",
> + .needs_cgroup_controllers = (const char *const []){ "cpuset", NULL },
> + .test_cgroup = &cg,
> };
>
> #else
> diff --git a/testcases/kernel/mem/ksm/ksm02.c b/testcases/kernel/mem/ksm/ksm02.c
> index c578cfb7f..7afa5ee12 100644
> --- a/testcases/kernel/mem/ksm/ksm02.c
> +++ b/testcases/kernel/mem/ksm/ksm02.c
> @@ -107,8 +107,6 @@ static void setup(void)
> SAFE_FILE_PRINTF(PATH_KSM "merge_across_nodes", "1");
> }
>
> - tst_cgroup_require("cpuset", NULL);
> - cg = tst_cgroup_get_test_group();
> cg_drain = tst_cgroup_get_drain_group();
> }
>
> @@ -129,6 +127,8 @@ static struct tst_test test = {
> },
> .test_all = verify_ksm,
> .min_kver = "2.6.32",
> + .needs_cgroup_controllers = (const char *const []){ "cpuset", NULL },
> + .test_cgroup = &cg,
> };
>
> #else
> diff --git a/testcases/kernel/mem/ksm/ksm03.c b/testcases/kernel/mem/ksm/ksm03.c
> index df847cf95..01a908b01 100644
> --- a/testcases/kernel/mem/ksm/ksm03.c
> +++ b/testcases/kernel/mem/ksm/ksm03.c
> @@ -79,8 +79,6 @@ static void setup(void)
>
> parse_ksm_options(opt_sizestr, &size, opt_numstr, &num, opt_unitstr, &unit);
>
> - tst_cgroup_require("memory", NULL);
> - cg = tst_cgroup_get_test_group();
> SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
> SAFE_CGROUP_PRINTF(cg, "memory.max", "%lu", TESTMEM);
> }
> @@ -110,4 +108,6 @@ static struct tst_test test = {
> },
> .test_all = verify_ksm,
> .min_kver = "2.6.32",
> + .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
> + .test_cgroup = &cg,
> };
> diff --git a/testcases/kernel/mem/ksm/ksm04.c b/testcases/kernel/mem/ksm/ksm04.c
> index e8bc1de85..0941fcc10 100644
> --- a/testcases/kernel/mem/ksm/ksm04.c
> +++ b/testcases/kernel/mem/ksm/ksm04.c
> @@ -106,9 +106,6 @@ static void setup(void)
>
> parse_ksm_options(opt_sizestr, &size, opt_numstr, &num, opt_unitstr, &unit);
>
> - tst_cgroup_require("memory", NULL);
> - tst_cgroup_require("cpuset", NULL);
> - cg = tst_cgroup_get_test_group();
> SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
> }
>
> @@ -129,6 +126,10 @@ static struct tst_test test = {
> },
> .test_all = verify_ksm,
> .min_kver = "2.6.32",
> + .needs_cgroup_controllers = (const char *const []){
> + "memory", "cpuset", NULL
> + },
> + .test_cgroup = &cg,
> };
>
> #else
> diff --git a/testcases/kernel/mem/oom/oom03.c b/testcases/kernel/mem/oom/oom03.c
> index 451119166..952c0d031 100644
> --- a/testcases/kernel/mem/oom/oom03.c
> +++ b/testcases/kernel/mem/oom/oom03.c
> @@ -84,8 +84,6 @@ static void setup(void)
> overcommit = get_sys_tune("overcommit_memory");
> set_sys_tune("overcommit_memory", 1, 1);
>
> - tst_cgroup_require("memory", NULL);
> - cg = tst_cgroup_get_test_group();
> SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
> SAFE_CGROUP_PRINTF(cg, "memory.max", "%lu", TESTMEM);
> }
> @@ -104,6 +102,8 @@ static struct tst_test test = {
> .setup = setup,
> .cleanup = cleanup,
> .test_all = verify_oom,
> + .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
> + .test_cgroup = &cg,
> };
>
> #else
> diff --git a/testcases/kernel/mem/oom/oom05.c b/testcases/kernel/mem/oom/oom05.c
> index 06497261e..ab2ad788b 100644
> --- a/testcases/kernel/mem/oom/oom05.c
> +++ b/testcases/kernel/mem/oom/oom05.c
> @@ -90,10 +90,6 @@ void setup(void)
> overcommit = get_sys_tune("overcommit_memory");
> set_sys_tune("overcommit_memory", 1, 1);
>
> - tst_cgroup_require("memory", NULL);
> - tst_cgroup_require("cpuset", NULL);
> - cg = tst_cgroup_get_test_group();
> -
> /*
> * Some nodes do not contain memory, so use
> * get_allowed_nodes(NH_MEMS) to get a memory
> @@ -124,6 +120,10 @@ static struct tst_test test = {
> .setup = setup,
> .cleanup = cleanup,
> .test_all = verify_oom,
> + .needs_cgroup_controllers = (const char *const []){
> + "memory", "cpuset", NULL
> + },
> + .test_cgroup = &cg,
> };
>
> #else
> diff --git a/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c b/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
> index e3eb237da..0c3146fb3 100644
> --- a/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
> +++ b/testcases/kernel/sched/cfs-scheduler/cfs_bandwidth01.c
> @@ -132,10 +132,6 @@ static void do_test(void)
>
> static void setup(void)
> {
> - tst_cgroup_require("cpu", NULL);
> -
> - cg_test = tst_cgroup_get_test_group();
> -
> cg_level2 = tst_cgroup_group_mk(cg_test, "level2");
>
> cg_level3a = tst_cgroup_group_mk(cg_level2, "level3a");
> @@ -182,6 +178,8 @@ static struct tst_test test = {
> "CONFIG_CFS_BANDWIDTH",
> NULL
> },
> + .needs_cgroup_controllers = (const char *const []){"cpu", NULL},
> + .test_cgroup = &cg_test,
> .tags = (const struct tst_tag[]) {
> {"linux-git", "39f23ce07b93"},
> {"linux-git", "b34cb07dde7c"},
> diff --git a/testcases/kernel/syscalls/madvise/madvise06.c b/testcases/kernel/syscalls/madvise/madvise06.c
> index 263b8e78b..4d8b6575d 100644
> --- a/testcases/kernel/syscalls/madvise/madvise06.c
> +++ b/testcases/kernel/syscalls/madvise/madvise06.c
> @@ -121,9 +121,6 @@ static void setup(void)
> check_path("/proc/self/oom_score_adj");
> SAFE_FILE_PRINTF("/proc/self/oom_score_adj", "%d", -1000);
>
> - tst_cgroup_require("memory", NULL);
> - cg = tst_cgroup_get_test_group();
> -
> SAFE_CGROUP_PRINTF(cg, "memory.max", "%ld", MEM_LIMIT);
> if (SAFE_CGROUP_HAS(cg, "memory.swap.max"))
> SAFE_CGROUP_PRINTF(cg, "memory.swap.max", "%ld", MEMSW_LIMIT);
> @@ -245,6 +242,8 @@ static struct tst_test test = {
> "?/proc/sys/vm/swappiness",
> NULL
> },
> + .needs_cgroup_controllers = (const char *const []){ "memory", NULL },
> + .test_cgroup = &cg,
> .tags = (const struct tst_tag[]) {
> {"linux-git", "55231e5c898c"},
> {"linux-git", "8de15e920dc8"},
> --
> 2.34.1
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest
2022-01-27 6:12 ` [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest Richard Palethorpe via ltp
2022-01-27 8:26 ` Richard Palethorpe
@ 2022-01-28 10:57 ` Cyril Hrubis
1 sibling, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2022-01-28 10:57 UTC (permalink / raw)
To: Richard Palethorpe; +Cc: ltp
Hi!
> +// SPDX-License-Identifier: GPL-2.0
> +/*\
> + *
> + * [Description]
> + *
> + * Conversion of the third kself test in cgroup/test_memcontrol.c.
> + *
> + * Original description:
> + * "First, this test creates the following hierarchy:
> + * A memory.min = 50M, memory.max = 200M
> + * A/B memory.min = 50M, memory.current = 50M
> + * A/B/C memory.min = 75M, memory.current = 50M
> + * A/B/D memory.min = 25M, memory.current = 50M
> + * A/B/E memory.min = 500M, memory.current = 0
> + * A/B/F memory.min = 0, memory.current = 50M
> + *
> + * Usages are pagecache, but the test keeps a running
> + * process in every leaf cgroup.
> + * Then it creates A/G and creates a significant
> + * memory pressure in it.
> + *
> + * A/B memory.current ~= 50M
> + * A/B/C memory.current ~= 33M
> + * A/B/D memory.current ~= 17M
> + * A/B/E memory.current ~= 0
> + *
> + * After that it tries to allocate more than there is unprotected
> + * memory in A available, and checks that memory.min protects
> + * pagecache even in this case."
> + *
> + * memory.min doesn't appear to exist on V1 so we only test on V2 like
> + * the selftest. We do test on more file systems, but not tempfs
> + * becaue it can't evict the page cache without swap. Also we avoid
> + * filesystems which allocate extra memory for buffer heads.
> + *
> + * The tolerances have been increased from the self tests.
> + *
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <inttypes.h>
> +
> +#include "memcontrol_common.h"
> +
> +#define TMPDIR "mntdir"
> +
> +static const struct tst_cgroup_group *cg_test;
> +static struct tst_cgroup_group *parent[3];
> +static struct tst_cgroup_group *children[4];
> +static int fd;
> +
> +enum checkpoints {
> + CHILD_IDLE,
> + TEST_DONE,
> +};
> +
> +static void cleanup_sub_groups(void)
> +{
> + size_t i;
> +
> + for (i = ARRAY_SIZE(children); i > 0; i--) {
> + if (!children[i - 1])
> + continue;
> +
> + TST_CHECKPOINT_WAKE2(TEST_DONE,
> + ARRAY_SIZE(children) - 1);
> + tst_reap_children();
> + break;
> + }
> +
> + for (i = ARRAY_SIZE(children); i > 0; i--) {
> + if (!children[i - 1])
> + continue;
> +
> + children[i - 1] = tst_cgroup_group_rm(children[i - 1]);
> + }
> +
> + for (i = ARRAY_SIZE(parent); i > 0; i--) {
> + if (!parent[i - 1])
> + continue;
> +
> + parent[i - 1] = tst_cgroup_group_rm(parent[i - 1]);
> + }
> +}
> +
> +static void alloc_anon_in_child(const struct tst_cgroup_group *const cg,
> + const size_t size, const int expect_oom)
> +{
> + int status;
> + const pid_t pid = SAFE_FORK();
> +
> + if (!pid) {
> + SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
> +
> + tst_res(TINFO, "%d in %s: Allocating anon: %"PRIdPTR,
> + getpid(), tst_cgroup_group_name(cg), size);
> + alloc_anon(size);
> + exit(0);
> + }
> +
> + if (expect_oom)
> + SAFE_WAITPID(pid, &status, 0);
> + else
> + tst_reap_child(pid);
I guess that we can do the SAFE_WAITPID() here in both cases but just
adjust expectations:
SAFE_WAITPID(pid, &status, 0);
if (WIFEXITTED(status) && WEXITSTATUS(status) == 0)
return;
if (expect_oom && WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)
return;
tst_res(TFAIL, "Child %s", tst_strstatus(status);
> +}
> +
> +static void alloc_pagecache_in_child(const struct tst_cgroup_group *const cg,
> + const size_t size)
> +{
> + const pid_t pid = SAFE_FORK();
> +
> + if (pid) {
> + TST_CHECKPOINT_WAIT(CHILD_IDLE);
> + return;
> + }
> +
> + SAFE_CGROUP_PRINTF(cg, "cgroup.procs", "%d", getpid());
> +
> + tst_res(TINFO, "%d in %s: Allocating pagecache: %"PRIdPTR,
> + getpid(), tst_cgroup_group_name(cg), size);
> + alloc_pagecache(fd, size);
> +
> + TST_CHECKPOINT_WAKE(CHILD_IDLE);
> + TST_CHECKPOINT_WAIT(TEST_DONE);
> + exit(0);
> +}
> +
> +/*
> + */
Empty comment.
> +static void test_memcg_min(void)
> +{
> + long c[4];
> + size_t i, attempts;
> + char child_name[64];
> +
> + fd = SAFE_OPEN(TMPDIR"/tmpfile", O_RDWR | O_CREAT, 0600);
> + parent[0] = tst_cgroup_group_mk(cg_test, "memcg_test_0");
> +
> + SAFE_CGROUP_SCANF(parent[0], "memory.min", "%ld", c);
> + if (c[0]) {
> + tst_brk(TCONF,
> + "memory.min already set to %ld on parent group", c[0]);
> + }
> +
> + if (!TST_CGROUP_VER_IS_V1(parent[0], "memory")) {
> + SAFE_CGROUP_PRINT(parent[0], "cgroup.subtree_control",
> + "+memory");
> + }
> + SAFE_CGROUP_PRINT(parent[0], "memory.max", "200M");
> + SAFE_CGROUP_PRINT(parent[0], "memory.swap.max", "0");
> +
> + parent[1] = tst_cgroup_group_mk(parent[0], "memcg_test_1");
> + if (!TST_CGROUP_VER_IS_V1(parent[0], "memory")) {
> + SAFE_CGROUP_PRINT(parent[1], "cgroup.subtree_control",
> + "+memory");
Don't we enable the memory controller automatically in the LTP library?
> + }
> +
> + parent[2] = tst_cgroup_group_mk(parent[0], "memcg_test_2");
> +
> + for (i = 0; i < ARRAY_SIZE(children); i++) {
> + sprintf(child_name, "child_memcg_%"PRIdPTR, i);
> +
> + children[i] = tst_cgroup_group_mk(parent[1], child_name);
I guess that it would be a bit more elegant if the tst_cgroup_group_mk()
would have been printf-like function.
> + if (i == 2)
> + continue;
> +
> + alloc_pagecache_in_child(children[i], MB(50));
> + }
> +
> + SAFE_CGROUP_PRINT(parent[0], "memory.min", "50M");
> + SAFE_CGROUP_PRINT(parent[1], "memory.min", "50M");
> + SAFE_CGROUP_PRINT(children[0], "memory.min", "75M");
> + SAFE_CGROUP_PRINT(children[1], "memory.min", "25M");
> + SAFE_CGROUP_PRINT(children[2], "memory.min", "500M");
> + SAFE_CGROUP_PRINT(children[3], "memory.min", "0");
> +
> + for (attempts = 0; attempts < 5; attempts++) {
> + SAFE_CGROUP_SCANF(parent[1], "memory.current", "%ld", c);
> + if (values_close(c[0], MB(150), 3))
> + break;
> +
> + sleep(1);
> + }
> +
> + alloc_anon_in_child(parent[2], MB(148), 0);
I find the usage of parent and child in the code a bit confusing, the
parent[2] is actually a child of parent[0].
Maybe we should call them "generation" such as gen1, gen2, etc.
So that we would have:
gen1 = tst_cgroup_group_mk(cg_test, "memcg_test_gen1");
gen2[0] = tst_cgroup_group_mk(gen1, "memcg_test_gen2_0");
gen2[1] = tst_cgroup_group_mk(gen2, "memcg_test_get2_1");
for (...)
gen3[i] = tst_cgroup_group_mk(gen2[0], "memcg_test_gen3_%i", i);
> + SAFE_CGROUP_SCANF(parent[1], "memory.current", "%ld", c);
> + TST_EXP_EXPR(values_close(c[0], MB(50), 5), "(A/B memory.current=%ld) ~= %d", c[0], MB(50));
> +
> + for (i = 0; i < ARRAY_SIZE(children); i++)
> + SAFE_CGROUP_SCANF(children[i], "memory.current", "%ld", c + i);
> +
> + TST_EXP_EXPR(values_close(c[0], MB(33), 20), "(A/B/C memory.current=%ld) ~= %d", c[0], MB(33));
> + TST_EXP_EXPR(values_close(c[1], MB(17), 20), "(A/B/D memory.current=%ld) ~= %d", c[1], MB(17));
> + TST_EXP_EXPR(values_close(c[2], 0, 1), "(A/B/E memory.current=%ld) ~= 0", c[2]);
> +
> + alloc_anon_in_child(parent[2], MB(170), 1);
> +
> + SAFE_CGROUP_SCANF(parent[1], "memory.current", "%ld", c);
> + TST_EXP_EXPR(values_close(c[0], MB(50), 5), "(A/B memory.current=%ld) ~= %d", c[0], MB(50));
> +
> + cleanup_sub_groups();
> + SAFE_CLOSE(fd);
> +}
> +
> +static void cleanup(void)
> +{
> + cleanup_sub_groups();
> + if (fd > -1)
> + SAFE_CLOSE(fd);
Technically this should either be fd > 0 or the global should be
initialized to -1.
> +}
> +
> +static struct tst_test test = {
> + .cleanup = cleanup,
> + .test_all = test_memcg_min,
> + .mount_device = 1,
> + .dev_min_size = 256,
> + .mntpoint = TMPDIR,
> + .all_filesystems = 1,
> + .skip_filesystems = (const char *const[]){
> + "exfat", "vfat", "fuse", "ntfs", "tmpfs", NULL
> + },
> + .forks_child = 1,
> + .needs_root = 1,
> + .needs_checkpoints = 1,
> + .needs_cgroup_ver = TST_CGROUP_V2,
> + .needs_cgroup_controllers = (const char *const[]){ "memory", NULL },
> + .test_cgroup = &cg_test,
> +};
> --
> 2.34.1
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2022-01-28 10:55 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-27 6:12 [LTP] [PATCH 0/6] Add memcontrol03 and declarative CG API Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 1/6] memcontrol02: Remove O_TMPFILE TCONF check Richard Palethorpe via ltp
2022-01-28 9:55 ` Cyril Hrubis
2022-01-27 6:12 ` [LTP] [PATCH 2/6] API: Add tst_reap_child Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 3/6] memcontrol: Lift out some common definitions into a shared header Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 4/6] API/cgroup: Declare required controllers and version in test struct Richard Palethorpe via ltp
2022-01-28 10:01 ` Cyril Hrubis
2022-01-27 6:12 ` [LTP] [PATCH 5/6] API/cgroup: Add memory.min Richard Palethorpe via ltp
2022-01-27 6:12 ` [LTP] [PATCH 6/6] memcontrol03: Copy from kselftest Richard Palethorpe via ltp
2022-01-27 8:26 ` Richard Palethorpe
2022-01-28 10:57 ` Cyril Hrubis
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.