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 |
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 --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
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