diff mbox series

[v3] cpuset02: Reimplementing the test6 of cpuset_memory_testset.sh as a separate C testcase

Message ID 20240926061936.21499-1-wegao@suse.com
State Changes Requested
Headers show
Series [v3] cpuset02: Reimplementing the test6 of cpuset_memory_testset.sh as a separate C testcase | expand

Commit Message

Wei Gao Sept. 26, 2024, 6:19 a.m. UTC
Signed-off-by: Wei Gao <wegao@suse.com>
---
 runtest/mm                                    |   1 +
 .../cpuset_memory_test/cpuset_memory_test.c   |  15 +-
 testcases/kernel/mem/.gitignore               |   1 +
 testcases/kernel/mem/cpuset/cpuset02.c        | 147 ++++++++++++++++++
 4 files changed, 158 insertions(+), 6 deletions(-)
 create mode 100644 testcases/kernel/mem/cpuset/cpuset02.c

Comments

Cyril Hrubis Sept. 27, 2024, 10:30 a.m. UTC | #1
Hi!
> diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore
> index d88484fa1..0845297cb 100644
> --- a/testcases/kernel/mem/.gitignore
> +++ b/testcases/kernel/mem/.gitignore
> @@ -1,4 +1,5 @@
>  /cpuset/cpuset01
> +/cpuset/cpuset02
>  /hugetlb/hugefallocate/hugefallocate01
>  /hugetlb/hugefallocate/hugefallocate02
>  /hugetlb/hugefork/hugefork01
> diff --git a/testcases/kernel/mem/cpuset/cpuset02.c b/testcases/kernel/mem/cpuset/cpuset02.c
> new file mode 100644
> index 000000000..05ed5c791
> --- /dev/null
> +++ b/testcases/kernel/mem/cpuset/cpuset02.c
> @@ -0,0 +1,147 @@
> +// SPDX-License-Identifier: LGPL-2.1-or-later
> +/*
> + * Copyright (c) 2009 FUJITSU LIMITED  Miao Xie <miaox@cn.fujitsu.com>
> + * Copyright (c) 2023 SUSE LLC <wegao@suse.com>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * This is reimplementing the test6 of cpuset_memory_testset.sh

This is _WRONG_.

You have to describe what the test does here, not where it came from.

> + */
> +
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <sys/mount.h>
> +#include <limits.h>
> +#include <sys/param.h>
> +#include <sys/types.h>
> +
> +#include "tst_test.h"
> +
> +#if HAVE_NUMA_H
> +#include <numa.h>
> +#endif
> +#if HAVE_NUMAIF_H
> +#include <numaif.h>
> +#endif
> +
> +#include "tst_safe_stdio.h"
> +#include "mem.h"
> +#include "numa_helper.h"
> +
> +#define MNTPOINT "hugetlbfs/"
> +#define CPUSET "cpuset_mnt"
> +
> +#ifdef HAVE_NUMA_V2
> +
> +static long hpage_size;
> +static int ncpus;
> +static int *nodes;
> +static int nnodes;
> +
> +static void count_cpus_mems(void)
> +{
> +	while (path_exist(PATH_SYS_SYSTEM "/cpu/cpu%d", ncpus))
> +		ncpus++;
> +	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.");
> +}

You must use the tst_get_nodemap() instead which also allows you to
specify how much free memory is required for each NUMA node.

> +static void run_test(void)
> +{
> +	char path[256];
> +	char tmp_path[256];
> +
> +	snprintf(path, sizeof(path), "./%s/0", CPUSET);
> +	if (access(path, F_OK) != 0)
> +		SAFE_MKDIR(path, 0777);
> +	snprintf(tmp_path, sizeof(tmp_path), "./%s/cpuset.cpus", path);
> +	SAFE_FILE_PRINTF(tmp_path, "%s", "0");
> +	snprintf(tmp_path, sizeof(tmp_path), "./%s/cpuset.mems", path);
> +	SAFE_FILE_PRINTF(tmp_path, "%s", "0");
> +	snprintf(tmp_path, sizeof(tmp_path), "./%s/cpuset.sched_load_balance", path);
> +	SAFE_FILE_PRINTF(tmp_path, "%s", "0");
> +	SAFE_FILE_PRINTF("/proc/sys/vm/nr_hugepages", "%d", 2 * nnodes);
> +
> +	int pid;
> +	char str_hpage_size[20];
> +
> +	snprintf(str_hpage_size, sizeof(str_hpage_size), "%ld", hpage_size);
> +	snprintf(tmp_path, sizeof(tmp_path), "%shugepagefile", MNTPOINT);
> +
> +	char *argv[10] = {
> +		"--mmap-file",
> +		"--hugepage",
> +		"-s",
> +		str_hpage_size,
> +		"-f",
> +		tmp_path,
> +		NULL,
> +	};
> +
> +	int fd = SAFE_OPEN("memory_result", O_WRONLY | O_CREAT | O_TRUNC, 0644);
> +
> +	SAFE_DUP2(fd, STDOUT_FILENO);
> +	pid = tst_run_script("cpuset_memory_test", argv);
> +	close(fd);
> +
> +	sleep(1);
> +	snprintf(tmp_path, sizeof(tmp_path), "./%s/tasks", path);
> +	SAFE_FILE_PRINTF(tmp_path, "%d", pid);
> +	kill(pid, SIGUSR1);
> +	sleep(1);
> +	kill(pid, SIGUSR1);
> +	sleep(1);
> +	kill(pid, SIGINT);
> +	SAFE_WAITPID(pid, NULL, 0);
> +
> +	char node[20];
> +	FILE *file;
> +
> +	file  = SAFE_FOPEN("memory_result", "r");
> +
> +	if (fgets(node, sizeof(node), file) == NULL)
> +		tst_res(TFAIL, "read memory_result failed");
> +
> +	fclose(file);

The whole point of the rewrite is to get rid of this mess where we
propagate the test results in files.

The code that allocates the memory has to be in this test and use proper
synchronization between processes, i.e. checkpoints. This would also
avoid the need to propagate test results because the forked child could
report results directly.

> +	TST_EXP_PASS(strncmp(node, "0", 1));
> +}
> +
> +static void setup(void)
> +{
> +	count_cpus_mems();
> +
> +	hpage_size = SAFE_READ_MEMINFO(MEMINFO_HPAGE_SIZE)*1024;
> +	SAFE_MKDIR(CPUSET, 0777);
> +	SAFE_MOUNT("cpuset", CPUSET, "cgroup", 0, "cpuset");

You have to use the .needs_cgroup_ctrls in tst_test instead.

> +}
> +
> +static void cleanup(void)
> +{
> +	SAFE_UMOUNT(CPUSET);
> +}
> +
> +static struct tst_test test = {
> +	.needs_root = 1,
> +	.runs_script = 1,
> +	.mntpoint = MNTPOINT,
> +	.needs_hugetlbfs = 1,
> +	.setup = setup,
> +	.forks_child = 1,
> +	.cleanup = cleanup,
> +	.test_all = run_test,
> +	.hugepages = {3, TST_NEEDS},
> +	.save_restore = (const struct tst_path_val[]) {
> +		{"/proc/sys/vm/nr_hugepages", NULL, TST_SR_TBROK},
> +		{}
> +	},
> +};
> +
> +#else
> +TST_TEST_TCONF(NUMA_ERROR_MSG);
> +#endif
> -- 
> 2.35.3
> 
> 
> -- 
> Mailing list info: https://lists.linux.it/listinfo/ltp
diff mbox series

Patch

diff --git a/runtest/mm b/runtest/mm
index 6a8cd0b9d..845874c41 100644
--- a/runtest/mm
+++ b/runtest/mm
@@ -75,6 +75,7 @@  ksm06_2 ksm06 -n 8000
 ksm07 ksm07
 
 cpuset01 cpuset01
+cpuset02 cpuset02
 
 oom01 oom01
 oom02 oom02
diff --git a/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_test.c b/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_test.c
index 9912d8d6a..4e9e40ea2 100644
--- a/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_test.c
+++ b/testcases/kernel/controllers/cpuset/cpuset_memory_test/cpuset_memory_test.c
@@ -56,10 +56,9 @@  static int opt_check; /* check node when munmap memory (only for mmap_anon()) */
 static int opt_thread;
 
 static int key_id;			/* used with opt_shm */
+static char hugepagefile[100] = "/hugetlb/hugepagefile";
 static unsigned long memsize;
 
-#define FILE_HUGEPAGE	"/hugetlb/hugepagefile"
-
 #define MMAP_ANON	(SCHAR_MAX + 1)
 #define MMAP_FILE	(SCHAR_MAX + 2)
 #define MMAP_LOCK1	(SCHAR_MAX + 3)
@@ -80,6 +79,7 @@  const struct option long_opts[] = {
 	{"thread", 0, NULL, THREAD},
 	{"size", 1, NULL, 's'},
 	{"key", 1, NULL, 'k'},
+	{"hugepage-file", 1, NULL, 'f'},
 	{NULL, 0, NULL, 0},
 };
 
@@ -92,7 +92,7 @@  void process_options(int argc, char *argv[])
 	char *end;
 
 	while (1) {
-		c = getopt_long(argc, argv, "s:k:", long_opts, NULL);
+		c = getopt_long(argc, argv, "s:k:f:", long_opts, NULL);
 		if (c == -1)
 			break;
 
@@ -105,6 +105,9 @@  void process_options(int argc, char *argv[])
 		case 'k':
 			key_id = atoi(optarg);
 			break;
+		case 'f':
+			strncpy(hugepagefile, optarg, sizeof(hugepagefile) - 1);
+			break;
 		case MMAP_ANON:
 			opt_mmap_anon = 1;
 			break;
@@ -179,7 +182,7 @@  void mmap_file(int flag_allocated)
 
 	if (!flag_allocated) {
 		if (opt_hugepage) {
-			fd_hugepage = open(FILE_HUGEPAGE,
+			fd_hugepage = open(hugepagefile,
 					   O_CREAT | O_RDWR, 0755);
 			if (fd_hugepage < 0)
 				err(1, "open hugepage file failed");
@@ -191,7 +194,7 @@  void mmap_file(int flag_allocated)
 			 MAP_SHARED, fd_tmp, 0);
 		if (p == MAP_FAILED) {
 			if (opt_hugepage)
-				unlink(FILE_HUGEPAGE);
+				unlink(hugepagefile);
 			err(1, "mmap(file) failed");
 		}
 		touch_memory_and_echo_node(p, memsize);
@@ -201,7 +204,7 @@  void mmap_file(int flag_allocated)
 
 		if (opt_hugepage) {
 			close(fd_hugepage);
-			unlink(FILE_HUGEPAGE);
+			unlink(hugepagefile);
 		}
 	}
 }
diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore
index d88484fa1..0845297cb 100644
--- a/testcases/kernel/mem/.gitignore
+++ b/testcases/kernel/mem/.gitignore
@@ -1,4 +1,5 @@ 
 /cpuset/cpuset01
+/cpuset/cpuset02
 /hugetlb/hugefallocate/hugefallocate01
 /hugetlb/hugefallocate/hugefallocate02
 /hugetlb/hugefork/hugefork01
diff --git a/testcases/kernel/mem/cpuset/cpuset02.c b/testcases/kernel/mem/cpuset/cpuset02.c
new file mode 100644
index 000000000..05ed5c791
--- /dev/null
+++ b/testcases/kernel/mem/cpuset/cpuset02.c
@@ -0,0 +1,147 @@ 
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * Copyright (c) 2009 FUJITSU LIMITED  Miao Xie <miaox@cn.fujitsu.com>
+ * Copyright (c) 2023 SUSE LLC <wegao@suse.com>
+ */
+
+/*\
+ * [Description]
+ *
+ * This is reimplementing the test6 of cpuset_memory_testset.sh
+ *
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <sys/mount.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include "tst_test.h"
+
+#if HAVE_NUMA_H
+#include <numa.h>
+#endif
+#if HAVE_NUMAIF_H
+#include <numaif.h>
+#endif
+
+#include "tst_safe_stdio.h"
+#include "mem.h"
+#include "numa_helper.h"
+
+#define MNTPOINT "hugetlbfs/"
+#define CPUSET "cpuset_mnt"
+
+#ifdef HAVE_NUMA_V2
+
+static long hpage_size;
+static int ncpus;
+static int *nodes;
+static int nnodes;
+
+static void count_cpus_mems(void)
+{
+	while (path_exist(PATH_SYS_SYSTEM "/cpu/cpu%d", ncpus))
+		ncpus++;
+	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.");
+}
+
+static void run_test(void)
+{
+	char path[256];
+	char tmp_path[256];
+
+	snprintf(path, sizeof(path), "./%s/0", CPUSET);
+	if (access(path, F_OK) != 0)
+		SAFE_MKDIR(path, 0777);
+	snprintf(tmp_path, sizeof(tmp_path), "./%s/cpuset.cpus", path);
+	SAFE_FILE_PRINTF(tmp_path, "%s", "0");
+	snprintf(tmp_path, sizeof(tmp_path), "./%s/cpuset.mems", path);
+	SAFE_FILE_PRINTF(tmp_path, "%s", "0");
+	snprintf(tmp_path, sizeof(tmp_path), "./%s/cpuset.sched_load_balance", path);
+	SAFE_FILE_PRINTF(tmp_path, "%s", "0");
+	SAFE_FILE_PRINTF("/proc/sys/vm/nr_hugepages", "%d", 2 * nnodes);
+
+	int pid;
+	char str_hpage_size[20];
+
+	snprintf(str_hpage_size, sizeof(str_hpage_size), "%ld", hpage_size);
+	snprintf(tmp_path, sizeof(tmp_path), "%shugepagefile", MNTPOINT);
+
+	char *argv[10] = {
+		"--mmap-file",
+		"--hugepage",
+		"-s",
+		str_hpage_size,
+		"-f",
+		tmp_path,
+		NULL,
+	};
+
+	int fd = SAFE_OPEN("memory_result", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+	SAFE_DUP2(fd, STDOUT_FILENO);
+	pid = tst_run_script("cpuset_memory_test", argv);
+	close(fd);
+
+	sleep(1);
+	snprintf(tmp_path, sizeof(tmp_path), "./%s/tasks", path);
+	SAFE_FILE_PRINTF(tmp_path, "%d", pid);
+	kill(pid, SIGUSR1);
+	sleep(1);
+	kill(pid, SIGUSR1);
+	sleep(1);
+	kill(pid, SIGINT);
+	SAFE_WAITPID(pid, NULL, 0);
+
+	char node[20];
+	FILE *file;
+
+	file  = SAFE_FOPEN("memory_result", "r");
+
+	if (fgets(node, sizeof(node), file) == NULL)
+		tst_res(TFAIL, "read memory_result failed");
+
+	fclose(file);
+
+	TST_EXP_PASS(strncmp(node, "0", 1));
+}
+
+static void setup(void)
+{
+	count_cpus_mems();
+
+	hpage_size = SAFE_READ_MEMINFO(MEMINFO_HPAGE_SIZE)*1024;
+	SAFE_MKDIR(CPUSET, 0777);
+	SAFE_MOUNT("cpuset", CPUSET, "cgroup", 0, "cpuset");
+}
+
+static void cleanup(void)
+{
+	SAFE_UMOUNT(CPUSET);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.runs_script = 1,
+	.mntpoint = MNTPOINT,
+	.needs_hugetlbfs = 1,
+	.setup = setup,
+	.forks_child = 1,
+	.cleanup = cleanup,
+	.test_all = run_test,
+	.hugepages = {3, TST_NEEDS},
+	.save_restore = (const struct tst_path_val[]) {
+		{"/proc/sys/vm/nr_hugepages", NULL, TST_SR_TBROK},
+		{}
+	},
+};
+
+#else
+TST_TEST_TCONF(NUMA_ERROR_MSG);
+#endif