@@ -75,6 +75,7 @@ ksm06_2 ksm06 -n 8000
ksm07 ksm07
cpuset01 cpuset01
+cpuset02 cpuset02
oom01 oom01
oom02 oom02
@@ -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);
}
}
}
@@ -1,4 +1,5 @@
/cpuset/cpuset01
+/cpuset/cpuset02
/hugetlb/hugefallocate/hugefallocate01
/hugetlb/hugefallocate/hugefallocate02
/hugetlb/hugefork/hugefork01
new file mode 100644
@@ -0,0 +1,152 @@
+// 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] = {
+ "cpuset_memory_test",
+ "--mmap-file",
+ "--hugepage",
+ "-s",
+ str_hpage_size,
+ "-f",
+ tmp_path,
+ NULL,
+ };
+
+ pid = SAFE_FORK();
+ if (pid == 0) {
+ int fd = SAFE_OPEN("memory_result", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+ SAFE_DUP2(fd, STDOUT_FILENO);
+ close(fd);
+ execvpe("cpuset_memory_test", argv, NULL);
+ tst_brk(TBROK | TERRNO, "execvpe(%s, ...) failed!", argv[0]);
+ exit(0);
+ }
+
+ 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,
+ .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 | 152 ++++++++++++++++++ 4 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 testcases/kernel/mem/cpuset/cpuset02.c