linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] Add selftests for mshare
@ 2025-08-25 14:57 Yongting Lin
  2025-08-25 14:57 ` [PATCH 1/8] mshare: Add selftests Yongting Lin
                   ` (16 more replies)
  0 siblings, 17 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

Mshare is a developing feature proposed by Anthony Yznaga and Khalid Aziz
that enables sharing of PTEs across processes. The V3 patch set has been
posted for review:

https://lore.kernel.org/linux-mm/20250820010415.699353-1-anthony.yznaga@oracle.com/

This patch set adds selftests to exercise and demonstrate basic
functionality of mshare.

The initial tests use open, ioctl, and mmap syscalls to establish a shared
memory mapping between two processes and verify the expected behavior.

Additional tests are included to check interoperability with swap and
Transparent Huge Pages.

Future work will extend coverage to other use cases such as integration
with KVM and more advanced scenarios.

This series is intended to be applied on top of mshare V3, which is
based on mm-new (2025-08-15).

Yongting Lin (8):
  mshare: Add selftests
  mshare: selftests: Adding config fragment
  mshare: selftests: Add some helper function for mshare filesystem
  mshare: selftests: Add test case shared memory
  mshare: selftests: Add test case ioctl unmap
  mshare: selftests: Add some helper functions for reading and
    controlling cgroup
  mshare: selftests: Add test case to demostrate the swaping of mshare
    memory
  mshare: selftests: Add test case to demostrate that mshare doesn't
    support THP

 tools/testing/selftests/mshare/.gitignore |   3 +
 tools/testing/selftests/mshare/Makefile   |   7 +
 tools/testing/selftests/mshare/basic.c    | 108 ++++++++++
 tools/testing/selftests/mshare/config     |   1 +
 tools/testing/selftests/mshare/memory.c   |  82 +++++++
 tools/testing/selftests/mshare/util.c     | 251 ++++++++++++++++++++++
 6 files changed, 452 insertions(+)
 create mode 100644 tools/testing/selftests/mshare/.gitignore
 create mode 100644 tools/testing/selftests/mshare/Makefile
 create mode 100644 tools/testing/selftests/mshare/basic.c
 create mode 100644 tools/testing/selftests/mshare/config
 create mode 100644 tools/testing/selftests/mshare/memory.c
 create mode 100644 tools/testing/selftests/mshare/util.c

-- 
2.20.1



^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/8] mshare: Add selftests
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 2/8] mshare: selftests: Adding config fragment Yongting Lin
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This patch sets up the selftests project for mshare and add a
'hello world' to project.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/.gitignore |  3 +++
 tools/testing/selftests/mshare/Makefile   |  7 +++++++
 tools/testing/selftests/mshare/basic.c    | 10 ++++++++++
 3 files changed, 20 insertions(+)
 create mode 100644 tools/testing/selftests/mshare/.gitignore
 create mode 100644 tools/testing/selftests/mshare/Makefile
 create mode 100644 tools/testing/selftests/mshare/basic.c

diff --git a/tools/testing/selftests/mshare/.gitignore b/tools/testing/selftests/mshare/.gitignore
new file mode 100644
index 000000000000..406f31bd432c
--- /dev/null
+++ b/tools/testing/selftests/mshare/.gitignore
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+basic
diff --git a/tools/testing/selftests/mshare/Makefile b/tools/testing/selftests/mshare/Makefile
new file mode 100644
index 000000000000..651658d091c5
--- /dev/null
+++ b/tools/testing/selftests/mshare/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+CFLAGS = $(KHDR_INCLUDES) -Wall -g -O2
+
+TEST_GEN_PROGS := basic
+
+include ../lib.mk
diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
new file mode 100644
index 000000000000..482af948878d
--- /dev/null
+++ b/tools/testing/selftests/mshare/basic.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "../kselftest_harness.h"
+
+TEST(basic)
+{
+	printf("Hello mshare\n");
+}
+
+TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/8] mshare: selftests: Adding config fragment
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
  2025-08-25 14:57 ` [PATCH 1/8] mshare: Add selftests Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem Yongting Lin
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

mshare test cases need pre-required kernel configs for the test
to get pass.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/config | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 tools/testing/selftests/mshare/config

diff --git a/tools/testing/selftests/mshare/config b/tools/testing/selftests/mshare/config
new file mode 100644
index 000000000000..16fd9a3ca12a
--- /dev/null
+++ b/tools/testing/selftests/mshare/config
@@ -0,0 +1 @@
+CONFIG_MSHARE=y
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
  2025-08-25 14:57 ` [PATCH 1/8] mshare: Add selftests Yongting Lin
  2025-08-25 14:57 ` [PATCH 2/8] mshare: selftests: Adding config fragment Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 4/8] mshare: selftests: Add test case shared memory Yongting Lin
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

Before create basic test cases, we need to have some helper functions
to help setup the tests.

These helper functions consist of:
  Mount and unmount the mshare filesystem
  Create a temporary file which be performed test on it later
  Map and unmap mshare region via the ioctl syscall

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/basic.c |   1 +
 tools/testing/selftests/mshare/util.c  | 123 +++++++++++++++++++++++++
 2 files changed, 124 insertions(+)
 create mode 100644 tools/testing/selftests/mshare/util.c

diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
index 482af948878d..35739b1133f7 100644
--- a/tools/testing/selftests/mshare/basic.c
+++ b/tools/testing/selftests/mshare/basic.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include "../kselftest_harness.h"
+#include "util.c"
 
 TEST(basic)
 {
diff --git a/tools/testing/selftests/mshare/util.c b/tools/testing/selftests/mshare/util.c
new file mode 100644
index 000000000000..75f6ff25aa2c
--- /dev/null
+++ b/tools/testing/selftests/mshare/util.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/msharefs.h>
+#include <stdio.h>
+#include <mntent.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/*
+ *  Helper functions for mounting msharefs
+ */
+
+#define MOUNT_POINT "/sys/fs/mshare"
+#define FS_TYPE     "msharefs"
+
+bool is_msharefs_mounted(void)
+{
+	FILE *fp;
+	struct mntent *ent;
+	bool found = false;
+
+	fp = setmntent("/proc/mounts", "r");
+	if (!fp) {
+		perror("setmntent");
+		exit(1);
+	}
+
+	while ((ent = getmntent(fp)) != NULL) {
+		if (strcmp(ent->mnt_dir, MOUNT_POINT) == 0 &&
+			strcmp(ent->mnt_type, FS_TYPE) == 0) {
+			found = true;
+			break;
+		}
+	}
+
+	endmntent(fp);
+	return found;
+}
+
+bool msharefs_premounted;
+
+__attribute__((constructor))
+void mount_sharefs(void)
+{
+	msharefs_premounted = is_msharefs_mounted();
+	if (msharefs_premounted)
+		return;
+
+	if (mount(FS_TYPE, MOUNT_POINT, FS_TYPE, 0, NULL) != 0) {
+		perror("mount");
+		exit(1);
+	}
+}
+
+__attribute__((destructor))
+void umount_sharefs(void)
+{
+	if (!msharefs_premounted && umount(MOUNT_POINT) != 0) {
+		perror("umount");
+		exit(1);
+	}
+}
+
+/*
+ *  Helper functions for mshare files
+ */
+
+#define MSHARE_INFO MOUNT_POINT "/mshare_info"
+#define MSHARE_TEST MOUNT_POINT "/mshare-test-XXXXXX"
+
+size_t mshare_get_info(void)
+{
+	char req[128];
+	size_t size;
+	int fd;
+
+	fd = open(MSHARE_INFO, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	read(fd, req, sizeof(req));
+	size = atoll(req);
+	close(fd);
+
+	return size;
+}
+
+int create_mshare_file(char *filename, size_t len)
+{
+	int fd;
+
+	strncpy(filename, MSHARE_TEST, len - 1);
+	fd = mkstemp(filename);
+
+	return fd;
+}
+
+
+int mshare_ioctl_mapping(int fd, size_t size, int flags)
+{
+	struct mshare_create mcreate;
+
+	mcreate.region_offset = 0;
+	mcreate.size = size;
+	mcreate.offset = 0;
+	mcreate.prot = PROT_READ | PROT_WRITE;
+	mcreate.flags = flags;
+	mcreate.fd = -1;
+
+	return ioctl(fd, MSHAREFS_CREATE_MAPPING, &mcreate);
+}
+
+int mshare_ioctl_munmap(int fd, size_t size)
+{
+	struct mshare_unmap munmap;
+
+	munmap.region_offset = 0;
+	munmap.size = size;
+
+	return ioctl(fd, MSHAREFS_UNMAP, &munmap);
+}
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/8] mshare: selftests: Add test case shared memory
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (2 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-29  0:59   ` Anthony Yznaga
  2025-08-25 14:57 ` [PATCH 5/8] mshare: selftests: Add test case ioctl unmap Yongting Lin
                   ` (12 subsequent siblings)
  16 siblings, 1 reply; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This test case aims to verify the basic functionalities of mshare.

Create a mshare file and use ioctl to create mapping for host mm
with supportive flags, then create two processes to map mshare file
to their memory spaces, and eventually verify the correctiness
of sharing memory.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/basic.c | 81 +++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
index 35739b1133f7..2347d30adfee 100644
--- a/tools/testing/selftests/mshare/basic.c
+++ b/tools/testing/selftests/mshare/basic.c
@@ -3,9 +3,86 @@
 #include "../kselftest_harness.h"
 #include "util.c"
 
-TEST(basic)
+#define STRING "I am Msharefs"
+
+FIXTURE(basic)
+{
+	char filename[128];
+	size_t align_size;
+	size_t allocate_size;
+};
+
+FIXTURE_VARIANT(basic) {
+	/* decide the time of real mapping size besed on align_size */
+	size_t map_size_time;
+	/* flags for ioctl */
+	int map_flags;
+};
+
+FIXTURE_VARIANT_ADD(basic, ANON_512G) {
+	.map_size_time = 1,
+	.map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_VARIANT_ADD(basic, HUGETLB_512G) {
+	.map_size_time = 1,
+	.map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_VARIANT_ADD(basic, ANON_1T) {
+	.map_size_time = 2,
+	.map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_VARIANT_ADD(basic, HUGETLB_1T) {
+	.map_size_time = 2,
+	.map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_SETUP(basic)
 {
-	printf("Hello mshare\n");
+	int fd;
+
+	self->align_size = mshare_get_info();
+	self->allocate_size = self->align_size * variant->map_size_time;
+
+	fd = create_mshare_file(self->filename, sizeof(self->filename));
+	ftruncate(fd, self->allocate_size);
+
+	ASSERT_EQ(mshare_ioctl_mapping(fd, self->allocate_size, variant->map_flags), 0);
+	close(fd);
+}
+
+FIXTURE_TEARDOWN(basic)
+{
+	ASSERT_EQ(unlink(self->filename), 0);
+}
+
+TEST_F(basic, shared_mem)
+{
+	int fd;
+	void *addr;
+	pid_t pid = fork();
+
+	ASSERT_NE(pid, -1);
+
+	fd = open(self->filename, O_RDWR, 0600);
+	ASSERT_NE(fd, -1);
+
+	addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
+		       MAP_SHARED, fd, 0);
+	ASSERT_NE(addr, MAP_FAILED);
+
+	if (pid == 0) {
+		/* Child process write date the shared memory */
+		memcpy(addr, STRING, sizeof(STRING));
+		exit(0);
+	}
+
+	ASSERT_NE(waitpid(pid, NULL, 0), -1);
+
+	/* Parent process should retrieve the data from the shared memory */
+	ASSERT_EQ(memcmp(addr, STRING, sizeof(STRING)), 0);
 }
 
 TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/8] mshare: selftests: Add test case ioctl unmap
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (3 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 4/8] mshare: selftests: Add test case shared memory Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup Yongting Lin
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This test case aims to verify whether the process with guest mm will
segfault when VMA of host mm is unmaped via ioctl(MSHAREFS_UNMAP).

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/basic.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
index 2347d30adfee..16d1f63c3ebe 100644
--- a/tools/testing/selftests/mshare/basic.c
+++ b/tools/testing/selftests/mshare/basic.c
@@ -85,4 +85,24 @@ TEST_F(basic, shared_mem)
 	ASSERT_EQ(memcmp(addr, STRING, sizeof(STRING)), 0);
 }
 
+TEST_F_SIGNAL(basic, ioctl_unmap, SIGSEGV)
+{
+	char *addr;
+	int fd;
+
+	fd = open(self->filename, O_RDWR, 0600);
+	addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
+			MAP_SHARED, fd, 0);
+	ASSERT_NE(addr, MAP_FAILED);
+	addr[0] = 'M';
+
+	/* munmap vma for host mm */
+	mshare_ioctl_munmap(fd, self->allocate_size);
+	/*
+	 * Will generate SIGSEGV signal as ioctl has already cleaned
+	 * shared page table
+	 */
+	addr[0] = 'D';
+}
+
 TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (4 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 5/8] mshare: selftests: Add test case ioctl unmap Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory Yongting Lin
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

Before verify some complicated memory functionalities such as swap memory
and THP, we need add some helper functions to controlling the cgroup
(specifically, memcg).

These helper functions consist:
  Create and destroy individual cgroup for test cases
  attach and dettach the test process to specified cgroup
  Read swap size and thp size from testing cgroup

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/util.c | 128 ++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/tools/testing/selftests/mshare/util.c b/tools/testing/selftests/mshare/util.c
index 75f6ff25aa2c..94fddaea2c56 100644
--- a/tools/testing/selftests/mshare/util.c
+++ b/tools/testing/selftests/mshare/util.c
@@ -121,3 +121,131 @@ int mshare_ioctl_munmap(int fd, size_t size)
 
 	return ioctl(fd, MSHAREFS_UNMAP, &munmap);
 }
+
+/*
+ * Helper functions for cgroup
+ */
+
+#define CGROUP_BASE "/sys/fs/cgroup/"
+#define CGROUP_TEST "mshare-test-XXXXXX"
+
+bool is_cgroup_v2;
+
+__attribute__((constructor))
+void get_cgroup_version(void)
+{
+	if (access(CGROUP_BASE "cgroup.controllers", F_OK) == 0)
+		is_cgroup_v2 = true;
+}
+
+int create_mshare_test_cgroup(char *cgroup, size_t len)
+{
+	if (is_cgroup_v2)
+		snprintf(cgroup, len, "%s/%s", CGROUP_BASE, CGROUP_TEST);
+	else
+		snprintf(cgroup, len, "%s/memory/%s", CGROUP_BASE, CGROUP_TEST);
+
+	char *path = mkdtemp(cgroup);
+
+	if (!path) {
+		perror("mkdtemp");
+		return -1;
+	}
+
+	return 0;
+}
+
+int remove_cgroup(char *cgroup)
+{
+	return rmdir(cgroup);
+}
+
+int write_data_to_cgroup(char *cgroup, char *file, char *data)
+{
+	char filename[128];
+	int fd;
+	int ret;
+
+	snprintf(filename, sizeof(filename), "%s/%s", cgroup, file);
+	fd = open(filename, O_RDWR);
+
+	if (fd == -1)
+		return -1;
+
+	ret = write(fd, data, strlen(data));
+	close(fd);
+
+	return ret;
+}
+
+int attach_to_cgroup(char *cgroup)
+{
+	char pid_str[32];
+
+	snprintf(pid_str, sizeof(pid_str), "%d", getpid());
+	return write_data_to_cgroup(cgroup, "cgroup.procs", pid_str);
+}
+
+/*
+ * Simplely, just move the pid to root memcg as avoid
+ * complicated consideration.
+ */
+int dettach_from_cgroup(char *cgroup)
+{
+	char pid_str[32];
+	char *root_memcg;
+
+	if (is_cgroup_v2)
+		root_memcg = CGROUP_BASE;
+	else
+		root_memcg = CGROUP_BASE "memory";
+
+	snprintf(pid_str, sizeof(pid_str), "%d", getpid());
+	return write_data_to_cgroup(root_memcg, "cgroup.procs", pid_str);
+}
+
+size_t read_data_from_cgroup(char *cgroup, char *file, char *field)
+{
+	char filename[128];
+	FILE *fp;
+	char line[80];
+	size_t size = -1;
+
+	snprintf(filename, sizeof(filename), "%s/%s", cgroup, file);
+	fp = fopen(filename, "r");
+	if (!fp) {
+		perror("fopen");
+		return -1;
+	}
+
+	while (fgets(line, sizeof(line), fp)) {
+		if (!strncmp(line, field, strlen(field))) {
+			char *value = line + strlen(field) + 1;
+
+			size = atol(value);
+			break;
+		}
+	}
+
+	fclose(fp);
+
+	return size;
+}
+
+size_t read_swap_from_cgroup(char *cgroup)
+{
+	if (is_cgroup_v2)
+		return read_data_from_cgroup(cgroup, "memory.stat", "pswpout");
+	else
+		return read_data_from_cgroup(cgroup, "memory.stat", "swap");
+}
+
+size_t read_huge_from_cgroup(char *cgroup)
+{
+	if (is_cgroup_v2)
+		return read_data_from_cgroup(cgroup, "memory.stat", "file_thp")
+		     + read_data_from_cgroup(cgroup, "memory.stat", "anon_thp")
+		     + read_data_from_cgroup(cgroup, "memory.stat", "shmem_thp");
+	else
+		return read_data_from_cgroup(cgroup, "memory.stat", "rss_huge");
+}
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (5 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP Yongting Lin
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This case is quit simple by using madvise(MADV_PAGEOUT), but for verifying
the memory size of being swaped, we need to setup the memcg and attach test
process to this memcg before perform the test.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/Makefile |  2 +-
 tools/testing/selftests/mshare/memory.c | 71 +++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/mshare/memory.c

diff --git a/tools/testing/selftests/mshare/Makefile b/tools/testing/selftests/mshare/Makefile
index 651658d091c5..b0418b8c30f2 100644
--- a/tools/testing/selftests/mshare/Makefile
+++ b/tools/testing/selftests/mshare/Makefile
@@ -2,6 +2,6 @@
 
 CFLAGS = $(KHDR_INCLUDES) -Wall -g -O2
 
-TEST_GEN_PROGS := basic
+TEST_GEN_PROGS := basic memory
 
 include ../lib.mk
diff --git a/tools/testing/selftests/mshare/memory.c b/tools/testing/selftests/mshare/memory.c
new file mode 100644
index 000000000000..7754c0e33506
--- /dev/null
+++ b/tools/testing/selftests/mshare/memory.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/mman.h>
+
+#include "../kselftest_harness.h"
+#include "util.c"
+
+#define GB(x) ((x) * (1UL << 30))
+
+FIXTURE(memory)
+{
+	char filename[128];
+	int fd;
+
+	char cgroup[128];
+
+	void *addr;
+	size_t allocate_size;
+};
+
+FIXTURE_SETUP(memory)
+{
+	ASSERT_NE(create_mshare_test_cgroup(self->cgroup, sizeof(self->cgroup)), -1);
+
+	attach_to_cgroup(self->cgroup);
+
+	self->allocate_size = mshare_get_info();
+	self->fd = create_mshare_file(self->filename, sizeof(self->filename));
+	ASSERT_NE(self->fd, -1);
+	ASSERT_NE(ftruncate(self->fd, self->allocate_size), -1);
+
+	ASSERT_NE(mshare_ioctl_mapping(self->fd, self->allocate_size,
+				MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED),
+			-1);
+	self->addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
+						MAP_SHARED, self->fd, 0);
+	ASSERT_NE(self->addr, MAP_FAILED);
+}
+
+FIXTURE_TEARDOWN(memory)
+{
+	ASSERT_NE(munmap(self->addr, self->allocate_size), -1);
+	close(self->fd);
+
+	ASSERT_NE(unlink(self->filename), -1);
+	dettach_from_cgroup(self->cgroup);
+
+	ASSERT_NE(remove_cgroup(self->cgroup), -1);
+}
+
+TEST_F(memory, swap)
+{
+	size_t swap_size;
+
+	/* touch 1G memory */
+	memset(self->addr, 0x01, GB(1));
+
+	/* force to reclaim the memory of mshare */
+	ASSERT_NE(madvise(self->addr, GB(1), MADV_PAGEOUT), -1);
+
+	swap_size = read_swap_from_cgroup(self->cgroup);
+	ASSERT_NE(swap_size, -1);
+
+	/* convert to bytes */
+	swap_size *= 4096;
+
+	/* allow an error of 10% */
+	ASSERT_GT(swap_size, GB(1) * 9 / 10);
+}
+
+TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (6 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-29  1:04   ` Anthony Yznaga
  2025-08-25 14:57 ` [PATCH 1/8] mshare: Add selftests Yongting Lin
                   ` (8 subsequent siblings)
  16 siblings, 1 reply; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This case is quit simple by using madvise(MADV_HUGEPAGE), but for verifying
the size of THP memory, we need to setup the memcg and attach test
process to this memcg before perform the test.

Because mshare doesn't support THP feature, the size of THP memory should
be 0 even though we use madivse.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/memory.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/testing/selftests/mshare/memory.c b/tools/testing/selftests/mshare/memory.c
index 7754c0e33506..2a415ce7bc01 100644
--- a/tools/testing/selftests/mshare/memory.c
+++ b/tools/testing/selftests/mshare/memory.c
@@ -68,4 +68,15 @@ TEST_F(memory, swap)
 	ASSERT_GT(swap_size, GB(1) * 9 / 10);
 }
 
+TEST_F(memory, thp)
+{
+	ASSERT_NE(madvise(self->addr, self->allocate_size, MADV_HUGEPAGE), -1);
+	/* touch 1G */
+	memset(self->addr, 0x01, GB(1));
+
+	size_t huge = read_huge_from_cgroup(self->cgroup);
+	/* mshare don't support THP now */
+	ASSERT_EQ(huge, 0);
+}
+
 TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 1/8] mshare: Add selftests
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (7 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 2/8] mshare: selftests: Adding config fragment Yongting Lin
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This patch sets up the selftests project for mshare and add a
'hello world' to project.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/.gitignore |  3 +++
 tools/testing/selftests/mshare/Makefile   |  7 +++++++
 tools/testing/selftests/mshare/basic.c    | 10 ++++++++++
 3 files changed, 20 insertions(+)
 create mode 100644 tools/testing/selftests/mshare/.gitignore
 create mode 100644 tools/testing/selftests/mshare/Makefile
 create mode 100644 tools/testing/selftests/mshare/basic.c

diff --git a/tools/testing/selftests/mshare/.gitignore b/tools/testing/selftests/mshare/.gitignore
new file mode 100644
index 000000000000..406f31bd432c
--- /dev/null
+++ b/tools/testing/selftests/mshare/.gitignore
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+basic
diff --git a/tools/testing/selftests/mshare/Makefile b/tools/testing/selftests/mshare/Makefile
new file mode 100644
index 000000000000..651658d091c5
--- /dev/null
+++ b/tools/testing/selftests/mshare/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+CFLAGS = $(KHDR_INCLUDES) -Wall -g -O2
+
+TEST_GEN_PROGS := basic
+
+include ../lib.mk
diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
new file mode 100644
index 000000000000..482af948878d
--- /dev/null
+++ b/tools/testing/selftests/mshare/basic.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include "../kselftest_harness.h"
+
+TEST(basic)
+{
+	printf("Hello mshare\n");
+}
+
+TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/8] mshare: selftests: Adding config fragment
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (8 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 1/8] mshare: Add selftests Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem Yongting Lin
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

mshare test cases need pre-required kernel configs for the test
to get pass.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/config | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 tools/testing/selftests/mshare/config

diff --git a/tools/testing/selftests/mshare/config b/tools/testing/selftests/mshare/config
new file mode 100644
index 000000000000..16fd9a3ca12a
--- /dev/null
+++ b/tools/testing/selftests/mshare/config
@@ -0,0 +1 @@
+CONFIG_MSHARE=y
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (9 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 2/8] mshare: selftests: Adding config fragment Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 4/8] mshare: selftests: Add test case shared memory Yongting Lin
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

Before create basic test cases, we need to have some helper functions
to help setup the tests.

These helper functions consist of:
  Mount and unmount the mshare filesystem
  Create a temporary file which be performed test on it later
  Map and unmap mshare region via the ioctl syscall

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/basic.c |   1 +
 tools/testing/selftests/mshare/util.c  | 123 +++++++++++++++++++++++++
 2 files changed, 124 insertions(+)
 create mode 100644 tools/testing/selftests/mshare/util.c

diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
index 482af948878d..35739b1133f7 100644
--- a/tools/testing/selftests/mshare/basic.c
+++ b/tools/testing/selftests/mshare/basic.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include "../kselftest_harness.h"
+#include "util.c"
 
 TEST(basic)
 {
diff --git a/tools/testing/selftests/mshare/util.c b/tools/testing/selftests/mshare/util.c
new file mode 100644
index 000000000000..75f6ff25aa2c
--- /dev/null
+++ b/tools/testing/selftests/mshare/util.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/msharefs.h>
+#include <stdio.h>
+#include <mntent.h>
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/*
+ *  Helper functions for mounting msharefs
+ */
+
+#define MOUNT_POINT "/sys/fs/mshare"
+#define FS_TYPE     "msharefs"
+
+bool is_msharefs_mounted(void)
+{
+	FILE *fp;
+	struct mntent *ent;
+	bool found = false;
+
+	fp = setmntent("/proc/mounts", "r");
+	if (!fp) {
+		perror("setmntent");
+		exit(1);
+	}
+
+	while ((ent = getmntent(fp)) != NULL) {
+		if (strcmp(ent->mnt_dir, MOUNT_POINT) == 0 &&
+			strcmp(ent->mnt_type, FS_TYPE) == 0) {
+			found = true;
+			break;
+		}
+	}
+
+	endmntent(fp);
+	return found;
+}
+
+bool msharefs_premounted;
+
+__attribute__((constructor))
+void mount_sharefs(void)
+{
+	msharefs_premounted = is_msharefs_mounted();
+	if (msharefs_premounted)
+		return;
+
+	if (mount(FS_TYPE, MOUNT_POINT, FS_TYPE, 0, NULL) != 0) {
+		perror("mount");
+		exit(1);
+	}
+}
+
+__attribute__((destructor))
+void umount_sharefs(void)
+{
+	if (!msharefs_premounted && umount(MOUNT_POINT) != 0) {
+		perror("umount");
+		exit(1);
+	}
+}
+
+/*
+ *  Helper functions for mshare files
+ */
+
+#define MSHARE_INFO MOUNT_POINT "/mshare_info"
+#define MSHARE_TEST MOUNT_POINT "/mshare-test-XXXXXX"
+
+size_t mshare_get_info(void)
+{
+	char req[128];
+	size_t size;
+	int fd;
+
+	fd = open(MSHARE_INFO, O_RDONLY);
+	if (fd == -1)
+		return -1;
+
+	read(fd, req, sizeof(req));
+	size = atoll(req);
+	close(fd);
+
+	return size;
+}
+
+int create_mshare_file(char *filename, size_t len)
+{
+	int fd;
+
+	strncpy(filename, MSHARE_TEST, len - 1);
+	fd = mkstemp(filename);
+
+	return fd;
+}
+
+
+int mshare_ioctl_mapping(int fd, size_t size, int flags)
+{
+	struct mshare_create mcreate;
+
+	mcreate.region_offset = 0;
+	mcreate.size = size;
+	mcreate.offset = 0;
+	mcreate.prot = PROT_READ | PROT_WRITE;
+	mcreate.flags = flags;
+	mcreate.fd = -1;
+
+	return ioctl(fd, MSHAREFS_CREATE_MAPPING, &mcreate);
+}
+
+int mshare_ioctl_munmap(int fd, size_t size)
+{
+	struct mshare_unmap munmap;
+
+	munmap.region_offset = 0;
+	munmap.size = size;
+
+	return ioctl(fd, MSHAREFS_UNMAP, &munmap);
+}
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/8] mshare: selftests: Add test case shared memory
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (10 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 5/8] mshare: selftests: Add test case ioctl unmap Yongting Lin
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This test case aims to verify the basic functionalities of mshare.

Create a mshare file and use ioctl to create mapping for host mm
with supportive flags, then create two processes to map mshare file
to their memory spaces, and eventually verify the correctiness
of sharing memory.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/basic.c | 81 +++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
index 35739b1133f7..2347d30adfee 100644
--- a/tools/testing/selftests/mshare/basic.c
+++ b/tools/testing/selftests/mshare/basic.c
@@ -3,9 +3,86 @@
 #include "../kselftest_harness.h"
 #include "util.c"
 
-TEST(basic)
+#define STRING "I am Msharefs"
+
+FIXTURE(basic)
+{
+	char filename[128];
+	size_t align_size;
+	size_t allocate_size;
+};
+
+FIXTURE_VARIANT(basic) {
+	/* decide the time of real mapping size besed on align_size */
+	size_t map_size_time;
+	/* flags for ioctl */
+	int map_flags;
+};
+
+FIXTURE_VARIANT_ADD(basic, ANON_512G) {
+	.map_size_time = 1,
+	.map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_VARIANT_ADD(basic, HUGETLB_512G) {
+	.map_size_time = 1,
+	.map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_VARIANT_ADD(basic, ANON_1T) {
+	.map_size_time = 2,
+	.map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_VARIANT_ADD(basic, HUGETLB_1T) {
+	.map_size_time = 2,
+	.map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
+};
+
+FIXTURE_SETUP(basic)
 {
-	printf("Hello mshare\n");
+	int fd;
+
+	self->align_size = mshare_get_info();
+	self->allocate_size = self->align_size * variant->map_size_time;
+
+	fd = create_mshare_file(self->filename, sizeof(self->filename));
+	ftruncate(fd, self->allocate_size);
+
+	ASSERT_EQ(mshare_ioctl_mapping(fd, self->allocate_size, variant->map_flags), 0);
+	close(fd);
+}
+
+FIXTURE_TEARDOWN(basic)
+{
+	ASSERT_EQ(unlink(self->filename), 0);
+}
+
+TEST_F(basic, shared_mem)
+{
+	int fd;
+	void *addr;
+	pid_t pid = fork();
+
+	ASSERT_NE(pid, -1);
+
+	fd = open(self->filename, O_RDWR, 0600);
+	ASSERT_NE(fd, -1);
+
+	addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
+		       MAP_SHARED, fd, 0);
+	ASSERT_NE(addr, MAP_FAILED);
+
+	if (pid == 0) {
+		/* Child process write date the shared memory */
+		memcpy(addr, STRING, sizeof(STRING));
+		exit(0);
+	}
+
+	ASSERT_NE(waitpid(pid, NULL, 0), -1);
+
+	/* Parent process should retrieve the data from the shared memory */
+	ASSERT_EQ(memcmp(addr, STRING, sizeof(STRING)), 0);
 }
 
 TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/8] mshare: selftests: Add test case ioctl unmap
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (11 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 4/8] mshare: selftests: Add test case shared memory Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup Yongting Lin
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This test case aims to verify whether the process with guest mm will
segfault when VMA of host mm is unmaped via ioctl(MSHAREFS_UNMAP).

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/basic.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
index 2347d30adfee..16d1f63c3ebe 100644
--- a/tools/testing/selftests/mshare/basic.c
+++ b/tools/testing/selftests/mshare/basic.c
@@ -85,4 +85,24 @@ TEST_F(basic, shared_mem)
 	ASSERT_EQ(memcmp(addr, STRING, sizeof(STRING)), 0);
 }
 
+TEST_F_SIGNAL(basic, ioctl_unmap, SIGSEGV)
+{
+	char *addr;
+	int fd;
+
+	fd = open(self->filename, O_RDWR, 0600);
+	addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
+			MAP_SHARED, fd, 0);
+	ASSERT_NE(addr, MAP_FAILED);
+	addr[0] = 'M';
+
+	/* munmap vma for host mm */
+	mshare_ioctl_munmap(fd, self->allocate_size);
+	/*
+	 * Will generate SIGSEGV signal as ioctl has already cleaned
+	 * shared page table
+	 */
+	addr[0] = 'D';
+}
+
 TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (12 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 5/8] mshare: selftests: Add test case ioctl unmap Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory Yongting Lin
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

Before verify some complicated memory functionalities such as swap memory
and THP, we need add some helper functions to controlling the cgroup
(specifically, memcg).

These helper functions consist:
  Create and destroy individual cgroup for test cases
  attach and dettach the test process to specified cgroup
  Read swap size and thp size from testing cgroup

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/util.c | 128 ++++++++++++++++++++++++++
 1 file changed, 128 insertions(+)

diff --git a/tools/testing/selftests/mshare/util.c b/tools/testing/selftests/mshare/util.c
index 75f6ff25aa2c..94fddaea2c56 100644
--- a/tools/testing/selftests/mshare/util.c
+++ b/tools/testing/selftests/mshare/util.c
@@ -121,3 +121,131 @@ int mshare_ioctl_munmap(int fd, size_t size)
 
 	return ioctl(fd, MSHAREFS_UNMAP, &munmap);
 }
+
+/*
+ * Helper functions for cgroup
+ */
+
+#define CGROUP_BASE "/sys/fs/cgroup/"
+#define CGROUP_TEST "mshare-test-XXXXXX"
+
+bool is_cgroup_v2;
+
+__attribute__((constructor))
+void get_cgroup_version(void)
+{
+	if (access(CGROUP_BASE "cgroup.controllers", F_OK) == 0)
+		is_cgroup_v2 = true;
+}
+
+int create_mshare_test_cgroup(char *cgroup, size_t len)
+{
+	if (is_cgroup_v2)
+		snprintf(cgroup, len, "%s/%s", CGROUP_BASE, CGROUP_TEST);
+	else
+		snprintf(cgroup, len, "%s/memory/%s", CGROUP_BASE, CGROUP_TEST);
+
+	char *path = mkdtemp(cgroup);
+
+	if (!path) {
+		perror("mkdtemp");
+		return -1;
+	}
+
+	return 0;
+}
+
+int remove_cgroup(char *cgroup)
+{
+	return rmdir(cgroup);
+}
+
+int write_data_to_cgroup(char *cgroup, char *file, char *data)
+{
+	char filename[128];
+	int fd;
+	int ret;
+
+	snprintf(filename, sizeof(filename), "%s/%s", cgroup, file);
+	fd = open(filename, O_RDWR);
+
+	if (fd == -1)
+		return -1;
+
+	ret = write(fd, data, strlen(data));
+	close(fd);
+
+	return ret;
+}
+
+int attach_to_cgroup(char *cgroup)
+{
+	char pid_str[32];
+
+	snprintf(pid_str, sizeof(pid_str), "%d", getpid());
+	return write_data_to_cgroup(cgroup, "cgroup.procs", pid_str);
+}
+
+/*
+ * Simplely, just move the pid to root memcg as avoid
+ * complicated consideration.
+ */
+int dettach_from_cgroup(char *cgroup)
+{
+	char pid_str[32];
+	char *root_memcg;
+
+	if (is_cgroup_v2)
+		root_memcg = CGROUP_BASE;
+	else
+		root_memcg = CGROUP_BASE "memory";
+
+	snprintf(pid_str, sizeof(pid_str), "%d", getpid());
+	return write_data_to_cgroup(root_memcg, "cgroup.procs", pid_str);
+}
+
+size_t read_data_from_cgroup(char *cgroup, char *file, char *field)
+{
+	char filename[128];
+	FILE *fp;
+	char line[80];
+	size_t size = -1;
+
+	snprintf(filename, sizeof(filename), "%s/%s", cgroup, file);
+	fp = fopen(filename, "r");
+	if (!fp) {
+		perror("fopen");
+		return -1;
+	}
+
+	while (fgets(line, sizeof(line), fp)) {
+		if (!strncmp(line, field, strlen(field))) {
+			char *value = line + strlen(field) + 1;
+
+			size = atol(value);
+			break;
+		}
+	}
+
+	fclose(fp);
+
+	return size;
+}
+
+size_t read_swap_from_cgroup(char *cgroup)
+{
+	if (is_cgroup_v2)
+		return read_data_from_cgroup(cgroup, "memory.stat", "pswpout");
+	else
+		return read_data_from_cgroup(cgroup, "memory.stat", "swap");
+}
+
+size_t read_huge_from_cgroup(char *cgroup)
+{
+	if (is_cgroup_v2)
+		return read_data_from_cgroup(cgroup, "memory.stat", "file_thp")
+		     + read_data_from_cgroup(cgroup, "memory.stat", "anon_thp")
+		     + read_data_from_cgroup(cgroup, "memory.stat", "shmem_thp");
+	else
+		return read_data_from_cgroup(cgroup, "memory.stat", "rss_huge");
+}
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (13 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-25 14:57 ` [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP Yongting Lin
  2025-08-26 11:16 ` [PATCH 0/8] Add selftests for mshare Yongting Lin
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This case is quit simple by using madvise(MADV_PAGEOUT), but for verifying
the memory size of being swaped, we need to setup the memcg and attach test
process to this memcg before perform the test.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/Makefile |  2 +-
 tools/testing/selftests/mshare/memory.c | 71 +++++++++++++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/mshare/memory.c

diff --git a/tools/testing/selftests/mshare/Makefile b/tools/testing/selftests/mshare/Makefile
index 651658d091c5..b0418b8c30f2 100644
--- a/tools/testing/selftests/mshare/Makefile
+++ b/tools/testing/selftests/mshare/Makefile
@@ -2,6 +2,6 @@
 
 CFLAGS = $(KHDR_INCLUDES) -Wall -g -O2
 
-TEST_GEN_PROGS := basic
+TEST_GEN_PROGS := basic memory
 
 include ../lib.mk
diff --git a/tools/testing/selftests/mshare/memory.c b/tools/testing/selftests/mshare/memory.c
new file mode 100644
index 000000000000..7754c0e33506
--- /dev/null
+++ b/tools/testing/selftests/mshare/memory.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/mman.h>
+
+#include "../kselftest_harness.h"
+#include "util.c"
+
+#define GB(x) ((x) * (1UL << 30))
+
+FIXTURE(memory)
+{
+	char filename[128];
+	int fd;
+
+	char cgroup[128];
+
+	void *addr;
+	size_t allocate_size;
+};
+
+FIXTURE_SETUP(memory)
+{
+	ASSERT_NE(create_mshare_test_cgroup(self->cgroup, sizeof(self->cgroup)), -1);
+
+	attach_to_cgroup(self->cgroup);
+
+	self->allocate_size = mshare_get_info();
+	self->fd = create_mshare_file(self->filename, sizeof(self->filename));
+	ASSERT_NE(self->fd, -1);
+	ASSERT_NE(ftruncate(self->fd, self->allocate_size), -1);
+
+	ASSERT_NE(mshare_ioctl_mapping(self->fd, self->allocate_size,
+				MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED),
+			-1);
+	self->addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
+						MAP_SHARED, self->fd, 0);
+	ASSERT_NE(self->addr, MAP_FAILED);
+}
+
+FIXTURE_TEARDOWN(memory)
+{
+	ASSERT_NE(munmap(self->addr, self->allocate_size), -1);
+	close(self->fd);
+
+	ASSERT_NE(unlink(self->filename), -1);
+	dettach_from_cgroup(self->cgroup);
+
+	ASSERT_NE(remove_cgroup(self->cgroup), -1);
+}
+
+TEST_F(memory, swap)
+{
+	size_t swap_size;
+
+	/* touch 1G memory */
+	memset(self->addr, 0x01, GB(1));
+
+	/* force to reclaim the memory of mshare */
+	ASSERT_NE(madvise(self->addr, GB(1), MADV_PAGEOUT), -1);
+
+	swap_size = read_swap_from_cgroup(self->cgroup);
+	ASSERT_NE(swap_size, -1);
+
+	/* convert to bytes */
+	swap_size *= 4096;
+
+	/* allow an error of 10% */
+	ASSERT_GT(swap_size, GB(1) * 9 / 10);
+}
+
+TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (14 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory Yongting Lin
@ 2025-08-25 14:57 ` Yongting Lin
  2025-08-26 11:16 ` [PATCH 0/8] Add selftests for mshare Yongting Lin
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-25 14:57 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

This case is quit simple by using madvise(MADV_HUGEPAGE), but for verifying
the size of THP memory, we need to setup the memcg and attach test
process to this memcg before perform the test.

Because mshare doesn't support THP feature, the size of THP memory should
be 0 even though we use madivse.

Signed-off-by: Yongting Lin <linyongting@bytedance.com>
---
 tools/testing/selftests/mshare/memory.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/testing/selftests/mshare/memory.c b/tools/testing/selftests/mshare/memory.c
index 7754c0e33506..2a415ce7bc01 100644
--- a/tools/testing/selftests/mshare/memory.c
+++ b/tools/testing/selftests/mshare/memory.c
@@ -68,4 +68,15 @@ TEST_F(memory, swap)
 	ASSERT_GT(swap_size, GB(1) * 9 / 10);
 }
 
+TEST_F(memory, thp)
+{
+	ASSERT_NE(madvise(self->addr, self->allocate_size, MADV_HUGEPAGE), -1);
+	/* touch 1G */
+	memset(self->addr, 0x01, GB(1));
+
+	size_t huge = read_huge_from_cgroup(self->cgroup);
+	/* mshare don't support THP now */
+	ASSERT_EQ(huge, 0);
+}
+
 TEST_HARNESS_MAIN
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 0/8] Add selftests for mshare
  2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
                   ` (15 preceding siblings ...)
  2025-08-25 14:57 ` [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP Yongting Lin
@ 2025-08-26 11:16 ` Yongting Lin
  16 siblings, 0 replies; 22+ messages in thread
From: Yongting Lin @ 2025-08-26 11:16 UTC (permalink / raw)
  To: anthony.yznaga, khalid, shuah, linyongting
  Cc: linux-kernel, linux-kselftest, akpm, linux-mm

Sorry for the mistake! I accidentally sent each individual patch twice,
except for the cover letter. Please ignore the duplicated ones at the
bottom.

Apologies again for the noise.

Yongting Lin.

On Mon, Aug 25, 2025 at 10:57 PM Yongting Lin <linyongting@bytedance.com> wrote:
>
> Mshare is a developing feature proposed by Anthony Yznaga and Khalid Aziz
> that enables sharing of PTEs across processes. The V3 patch set has been
> posted for review:
>
> https://lore.kernel.org/linux-mm/20250820010415.699353-1-anthony.yznaga@oracle.com/
>
> This patch set adds selftests to exercise and demonstrate basic
> functionality of mshare.
>
> The initial tests use open, ioctl, and mmap syscalls to establish a shared
> memory mapping between two processes and verify the expected behavior.
>
> Additional tests are included to check interoperability with swap and
> Transparent Huge Pages.
>
> Future work will extend coverage to other use cases such as integration
> with KVM and more advanced scenarios.
>
> This series is intended to be applied on top of mshare V3, which is
> based on mm-new (2025-08-15).
>
> Yongting Lin (8):
>   mshare: Add selftests
>   mshare: selftests: Adding config fragment
>   mshare: selftests: Add some helper function for mshare filesystem
>   mshare: selftests: Add test case shared memory
>   mshare: selftests: Add test case ioctl unmap
>   mshare: selftests: Add some helper functions for reading and
>     controlling cgroup
>   mshare: selftests: Add test case to demostrate the swaping of mshare
>     memory
>   mshare: selftests: Add test case to demostrate that mshare doesn't
>     support THP
>
>  tools/testing/selftests/mshare/.gitignore |   3 +
>  tools/testing/selftests/mshare/Makefile   |   7 +
>  tools/testing/selftests/mshare/basic.c    | 108 ++++++++++
>  tools/testing/selftests/mshare/config     |   1 +
>  tools/testing/selftests/mshare/memory.c   |  82 +++++++
>  tools/testing/selftests/mshare/util.c     | 251 ++++++++++++++++++++++
>  6 files changed, 452 insertions(+)
>  create mode 100644 tools/testing/selftests/mshare/.gitignore
>  create mode 100644 tools/testing/selftests/mshare/Makefile
>  create mode 100644 tools/testing/selftests/mshare/basic.c
>  create mode 100644 tools/testing/selftests/mshare/config
>  create mode 100644 tools/testing/selftests/mshare/memory.c
>  create mode 100644 tools/testing/selftests/mshare/util.c
>
> --
> 2.20.1
>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/8] mshare: selftests: Add test case shared memory
  2025-08-25 14:57 ` [PATCH 4/8] mshare: selftests: Add test case shared memory Yongting Lin
@ 2025-08-29  0:59   ` Anthony Yznaga
  2025-09-01 12:50     ` [External] " Yongting Lin
  0 siblings, 1 reply; 22+ messages in thread
From: Anthony Yznaga @ 2025-08-29  0:59 UTC (permalink / raw)
  To: Yongting Lin, khalid, shuah; +Cc: linux-kernel, linux-kselftest, akpm, linux-mm

Hi Yongting,

Thank you for doing this. This is a great start for testing mshare.
I do have some comments below.

On 8/25/25 7:57 AM, Yongting Lin wrote:
> This test case aims to verify the basic functionalities of mshare.
> 
> Create a mshare file and use ioctl to create mapping for host mm
> with supportive flags, then create two processes to map mshare file
> to their memory spaces, and eventually verify the correctiness
> of sharing memory.
> 
> Signed-off-by: Yongting Lin <linyongting@bytedance.com>
> ---
>   tools/testing/selftests/mshare/basic.c | 81 +++++++++++++++++++++++++-
>   1 file changed, 79 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
> index 35739b1133f7..2347d30adfee 100644
> --- a/tools/testing/selftests/mshare/basic.c
> +++ b/tools/testing/selftests/mshare/basic.c
> @@ -3,9 +3,86 @@
>   #include "../kselftest_harness.h"
>   #include "util.c"
>   
> -TEST(basic)
> +#define STRING "I am Msharefs"
> +
> +FIXTURE(basic)
> +{
> +	char filename[128];
> +	size_t align_size;
> +	size_t allocate_size;
> +};
> +
> +FIXTURE_VARIANT(basic) {
> +	/* decide the time of real mapping size besed on align_size */
> +	size_t map_size_time;
> +	/* flags for ioctl */
> +	int map_flags;
> +};
> +
> +FIXTURE_VARIANT_ADD(basic, ANON_512G) {
> +	.map_size_time = 1,
> +	.map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
> +};
> +
> +FIXTURE_VARIANT_ADD(basic, HUGETLB_512G) {
> +	.map_size_time = 1,
> +	.map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
> +};
> +
> +FIXTURE_VARIANT_ADD(basic, ANON_1T) {
> +	.map_size_time = 2,
> +	.map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
> +};
> +
> +FIXTURE_VARIANT_ADD(basic, HUGETLB_1T) {
> +	.map_size_time = 2,
> +	.map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
> +};
> +
> +FIXTURE_SETUP(basic)
>   {
> -	printf("Hello mshare\n");
> +	int fd;
> +
> +	self->align_size = mshare_get_info();
> +	self->allocate_size = self->align_size * variant->map_size_time;
> +
> +	fd = create_mshare_file(self->filename, sizeof(self->filename));
> +	ftruncate(fd, self->allocate_size);
> +
> +	ASSERT_EQ(mshare_ioctl_mapping(fd, self->allocate_size, variant->map_flags), 0);

The tests should differentiate between how much VA space is allocated to 
an mshare region (i.e with ftruncate()) and how much memory is allocated 
within an mshare region through the ioctl. While the bounds of an mshare 
region need to be aligned to 512 GB, the memory allocated within it does 
not. Right now the tests will try to map 512 GB or 1 TB of anon or 
hugetlb memory in an mshare region which will fail on smaller systems to 
due to insufficient memory. Better to allocate smaller amounts so the 
tests can run on more systems.

Anthony

> +	close(fd);
> +}
> +
> +FIXTURE_TEARDOWN(basic)
> +{
> +	ASSERT_EQ(unlink(self->filename), 0);
> +}
> +
> +TEST_F(basic, shared_mem)
> +{
> +	int fd;
> +	void *addr;
> +	pid_t pid = fork();
> +
> +	ASSERT_NE(pid, -1);
> +
> +	fd = open(self->filename, O_RDWR, 0600);
> +	ASSERT_NE(fd, -1);
> +
> +	addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
> +		       MAP_SHARED, fd, 0);
> +	ASSERT_NE(addr, MAP_FAILED);
> +
> +	if (pid == 0) {
> +		/* Child process write date the shared memory */
> +		memcpy(addr, STRING, sizeof(STRING));
> +		exit(0);
> +	}
> +
> +	ASSERT_NE(waitpid(pid, NULL, 0), -1);
> +
> +	/* Parent process should retrieve the data from the shared memory */
> +	ASSERT_EQ(memcmp(addr, STRING, sizeof(STRING)), 0);
>   }
>   
>   TEST_HARNESS_MAIN



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP
  2025-08-25 14:57 ` [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP Yongting Lin
@ 2025-08-29  1:04   ` Anthony Yznaga
  0 siblings, 0 replies; 22+ messages in thread
From: Anthony Yznaga @ 2025-08-29  1:04 UTC (permalink / raw)
  To: Yongting Lin, khalid, shuah; +Cc: linux-kernel, linux-kselftest, akpm, linux-mm



On 8/25/25 7:57 AM, Yongting Lin wrote:
> This case is quit simple by using madvise(MADV_HUGEPAGE), but for verifying
> the size of THP memory, we need to setup the memcg and attach test
> process to this memcg before perform the test.
> 
> Because mshare doesn't support THP feature, the size of THP memory should
> be 0 even though we use madivse.

There can be THPs in an mshare region if THP settings are set to 
"always", but otherwise madvise() won't work directly on the msharefs 
VMA. It will be necessary to implement an ioctl to apply madvise 
operations to memory in an mshare region.

Anthony

> 
> Signed-off-by: Yongting Lin <linyongting@bytedance.com>
> ---
>   tools/testing/selftests/mshare/memory.c | 11 +++++++++++
>   1 file changed, 11 insertions(+)
> 
> diff --git a/tools/testing/selftests/mshare/memory.c b/tools/testing/selftests/mshare/memory.c
> index 7754c0e33506..2a415ce7bc01 100644
> --- a/tools/testing/selftests/mshare/memory.c
> +++ b/tools/testing/selftests/mshare/memory.c
> @@ -68,4 +68,15 @@ TEST_F(memory, swap)
>   	ASSERT_GT(swap_size, GB(1) * 9 / 10);
>   }
>   
> +TEST_F(memory, thp)
> +{
> +	ASSERT_NE(madvise(self->addr, self->allocate_size, MADV_HUGEPAGE), -1);
> +	/* touch 1G */
> +	memset(self->addr, 0x01, GB(1));
> +
> +	size_t huge = read_huge_from_cgroup(self->cgroup);
> +	/* mshare don't support THP now */
> +	ASSERT_EQ(huge, 0);
> +}
> +
>   TEST_HARNESS_MAIN



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [External] Re: [PATCH 4/8] mshare: selftests: Add test case shared memory
  2025-08-29  0:59   ` Anthony Yznaga
@ 2025-09-01 12:50     ` Yongting Lin
  2025-09-02 21:34       ` Anthony Yznaga
  0 siblings, 1 reply; 22+ messages in thread
From: Yongting Lin @ 2025-09-01 12:50 UTC (permalink / raw)
  To: Anthony Yznaga
  Cc: khalid, shuah, linux-kernel, linux-kselftest, akpm, linux-mm

On Fri, Aug 29, 2025 at 9:00 AM Anthony Yznaga
<anthony.yznaga@oracle.com> wrote:
>
> Hi Yongting,
>
> Thank you for doing this. This is a great start for testing mshare.
> I do have some comments below.
>
> On 8/25/25 7:57 AM, Yongting Lin wrote:
> > This test case aims to verify the basic functionalities of mshare.
> >
> > Create a mshare file and use ioctl to create mapping for host mm
> > with supportive flags, then create two processes to map mshare file
> > to their memory spaces, and eventually verify the correctiness
> > of sharing memory.
> >
> > Signed-off-by: Yongting Lin <linyongting@bytedance.com>
> > ---
> >   tools/testing/selftests/mshare/basic.c | 81 +++++++++++++++++++++++++-
> >   1 file changed, 79 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
> > index 35739b1133f7..2347d30adfee 100644
> > --- a/tools/testing/selftests/mshare/basic.c
> > +++ b/tools/testing/selftests/mshare/basic.c
> > @@ -3,9 +3,86 @@
> >   #include "../kselftest_harness.h"
> >   #include "util.c"
> >
> > -TEST(basic)
> > +#define STRING "I am Msharefs"
> > +
> > +FIXTURE(basic)
> > +{
> > +     char filename[128];
> > +     size_t align_size;
> > +     size_t allocate_size;
> > +};
> > +
> > +FIXTURE_VARIANT(basic) {
> > +     /* decide the time of real mapping size besed on align_size */
> > +     size_t map_size_time;
> > +     /* flags for ioctl */
> > +     int map_flags;
> > +};
> > +
> > +FIXTURE_VARIANT_ADD(basic, ANON_512G) {
> > +     .map_size_time = 1,
> > +     .map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
> > +};
> > +
> > +FIXTURE_VARIANT_ADD(basic, HUGETLB_512G) {
> > +     .map_size_time = 1,
> > +     .map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
> > +};
> > +
> > +FIXTURE_VARIANT_ADD(basic, ANON_1T) {
> > +     .map_size_time = 2,
> > +     .map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
> > +};
> > +
> > +FIXTURE_VARIANT_ADD(basic, HUGETLB_1T) {
> > +     .map_size_time = 2,
> > +     .map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
> > +};
> > +
> > +FIXTURE_SETUP(basic)
> >   {
> > -     printf("Hello mshare\n");
> > +     int fd;
> > +
> > +     self->align_size = mshare_get_info();
> > +     self->allocate_size = self->align_size * variant->map_size_time;
> > +
> > +     fd = create_mshare_file(self->filename, sizeof(self->filename));
> > +     ftruncate(fd, self->allocate_size);
> > +
> > +     ASSERT_EQ(mshare_ioctl_mapping(fd, self->allocate_size, variant->map_flags), 0);
>
> The tests should differentiate between how much VA space is allocated to
> an mshare region (i.e with ftruncate()) and how much memory is allocated
> within an mshare region through the ioctl. While the bounds of an mshare
> region need to be aligned to 512 GB, the memory allocated within it does
> not. Right now the tests will try to map 512 GB or 1 TB of anon or
> hugetlb memory in an mshare region which will fail on smaller systems to
> due to insufficient memory. Better to allocate smaller amounts so the
> tests can run on more systems.
>
> Anthony

I Changed my code to allocate a smaller chunk of memory (i.e.
4K/8K/2M/4M), and these tests are passed.

But I found something different:
step1:  ftruncate a mshare file to 512G
step2:  ioctl map 8K
step3: but after that, I am going to mmap 8K to a process but it
fails, then I have up to mmap 512G memory to process.
step4: Accessing the memory within the 8K boundary is fine but get
segfault after exceling the boundary (as the vma of host mm only holds
a memory region of 8K)

Should the mmap region keep consistent with the ioctl map region in
size? (currently, ioctl map region is 8K, but mmap region is 512G)

Yongting
>
> > +     close(fd);
> > +}
> > +
> > +FIXTURE_TEARDOWN(basic)
> > +{
> > +     ASSERT_EQ(unlink(self->filename), 0);
> > +}
> > +
> > +TEST_F(basic, shared_mem)
> > +{
> > +     int fd;
> > +     void *addr;
> > +     pid_t pid = fork();
> > +
> > +     ASSERT_NE(pid, -1);
> > +
> > +     fd = open(self->filename, O_RDWR, 0600);
> > +     ASSERT_NE(fd, -1);
> > +
> > +     addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
> > +                    MAP_SHARED, fd, 0);
> > +     ASSERT_NE(addr, MAP_FAILED);
> > +
> > +     if (pid == 0) {
> > +             /* Child process write date the shared memory */
> > +             memcpy(addr, STRING, sizeof(STRING));
> > +             exit(0);
> > +     }
> > +
> > +     ASSERT_NE(waitpid(pid, NULL, 0), -1);
> > +
> > +     /* Parent process should retrieve the data from the shared memory */
> > +     ASSERT_EQ(memcmp(addr, STRING, sizeof(STRING)), 0);
> >   }
> >
> >   TEST_HARNESS_MAIN
>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [External] Re: [PATCH 4/8] mshare: selftests: Add test case shared memory
  2025-09-01 12:50     ` [External] " Yongting Lin
@ 2025-09-02 21:34       ` Anthony Yznaga
  0 siblings, 0 replies; 22+ messages in thread
From: Anthony Yznaga @ 2025-09-02 21:34 UTC (permalink / raw)
  To: Yongting Lin; +Cc: khalid, shuah, linux-kernel, linux-kselftest, akpm, linux-mm



On 9/1/25 5:50 AM, Yongting Lin wrote:
> On Fri, Aug 29, 2025 at 9:00 AM Anthony Yznaga
> <anthony.yznaga@oracle.com> wrote:
>>
>> Hi Yongting,
>>
>> Thank you for doing this. This is a great start for testing mshare.
>> I do have some comments below.
>>
>> On 8/25/25 7:57 AM, Yongting Lin wrote:
>>> This test case aims to verify the basic functionalities of mshare.
>>>
>>> Create a mshare file and use ioctl to create mapping for host mm
>>> with supportive flags, then create two processes to map mshare file
>>> to their memory spaces, and eventually verify the correctiness
>>> of sharing memory.
>>>
>>> Signed-off-by: Yongting Lin <linyongting@bytedance.com>
>>> ---
>>>    tools/testing/selftests/mshare/basic.c | 81 +++++++++++++++++++++++++-
>>>    1 file changed, 79 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/tools/testing/selftests/mshare/basic.c b/tools/testing/selftests/mshare/basic.c
>>> index 35739b1133f7..2347d30adfee 100644
>>> --- a/tools/testing/selftests/mshare/basic.c
>>> +++ b/tools/testing/selftests/mshare/basic.c
>>> @@ -3,9 +3,86 @@
>>>    #include "../kselftest_harness.h"
>>>    #include "util.c"
>>>
>>> -TEST(basic)
>>> +#define STRING "I am Msharefs"
>>> +
>>> +FIXTURE(basic)
>>> +{
>>> +     char filename[128];
>>> +     size_t align_size;
>>> +     size_t allocate_size;
>>> +};
>>> +
>>> +FIXTURE_VARIANT(basic) {
>>> +     /* decide the time of real mapping size besed on align_size */
>>> +     size_t map_size_time;
>>> +     /* flags for ioctl */
>>> +     int map_flags;
>>> +};
>>> +
>>> +FIXTURE_VARIANT_ADD(basic, ANON_512G) {
>>> +     .map_size_time = 1,
>>> +     .map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
>>> +};
>>> +
>>> +FIXTURE_VARIANT_ADD(basic, HUGETLB_512G) {
>>> +     .map_size_time = 1,
>>> +     .map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
>>> +};
>>> +
>>> +FIXTURE_VARIANT_ADD(basic, ANON_1T) {
>>> +     .map_size_time = 2,
>>> +     .map_flags = MAP_ANONYMOUS | MAP_SHARED | MAP_FIXED,
>>> +};
>>> +
>>> +FIXTURE_VARIANT_ADD(basic, HUGETLB_1T) {
>>> +     .map_size_time = 2,
>>> +     .map_flags = MAP_ANONYMOUS | MAP_HUGETLB | MAP_SHARED | MAP_FIXED,
>>> +};
>>> +
>>> +FIXTURE_SETUP(basic)
>>>    {
>>> -     printf("Hello mshare\n");
>>> +     int fd;
>>> +
>>> +     self->align_size = mshare_get_info();
>>> +     self->allocate_size = self->align_size * variant->map_size_time;
>>> +
>>> +     fd = create_mshare_file(self->filename, sizeof(self->filename));
>>> +     ftruncate(fd, self->allocate_size);
>>> +
>>> +     ASSERT_EQ(mshare_ioctl_mapping(fd, self->allocate_size, variant->map_flags), 0);
>>
>> The tests should differentiate between how much VA space is allocated to
>> an mshare region (i.e with ftruncate()) and how much memory is allocated
>> within an mshare region through the ioctl. While the bounds of an mshare
>> region need to be aligned to 512 GB, the memory allocated within it does
>> not. Right now the tests will try to map 512 GB or 1 TB of anon or
>> hugetlb memory in an mshare region which will fail on smaller systems to
>> due to insufficient memory. Better to allocate smaller amounts so the
>> tests can run on more systems.
>>
>> Anthony
> 
> I Changed my code to allocate a smaller chunk of memory (i.e.
> 4K/8K/2M/4M), and these tests are passed.
> 
> But I found something different:
> step1:  ftruncate a mshare file to 512G
> step2:  ioctl map 8K
> step3: but after that, I am going to mmap 8K to a process but it
> fails, then I have up to mmap 512G memory to process.

This is correct. For page table sharing to work correctly the entire 
range of the mshare region must be mmap'd into the process even though 
the amount of memory actually mapped within the region via ioctl() may 
be much smaller.

> step4: Accessing the memory within the 8K boundary is fine but get
> segfault after exceling the boundary (as the vma of host mm only holds
> a memory region of 8K)
> 
> Should the mmap region keep consistent with the ioctl map region in
> size? (currently, ioctl map region is 8K, but mmap region is 512G)

It might help to think of the 512G mmap region as a window that gives 
the process visbility or access to the actual memory that is mapped 
within the mshare region.

Anthony


> 
> Yongting
>>
>>> +     close(fd);
>>> +}
>>> +
>>> +FIXTURE_TEARDOWN(basic)
>>> +{
>>> +     ASSERT_EQ(unlink(self->filename), 0);
>>> +}
>>> +
>>> +TEST_F(basic, shared_mem)
>>> +{
>>> +     int fd;
>>> +     void *addr;
>>> +     pid_t pid = fork();
>>> +
>>> +     ASSERT_NE(pid, -1);
>>> +
>>> +     fd = open(self->filename, O_RDWR, 0600);
>>> +     ASSERT_NE(fd, -1);
>>> +
>>> +     addr = mmap(NULL, self->allocate_size, PROT_READ | PROT_WRITE,
>>> +                    MAP_SHARED, fd, 0);
>>> +     ASSERT_NE(addr, MAP_FAILED);
>>> +
>>> +     if (pid == 0) {
>>> +             /* Child process write date the shared memory */
>>> +             memcpy(addr, STRING, sizeof(STRING));
>>> +             exit(0);
>>> +     }
>>> +
>>> +     ASSERT_NE(waitpid(pid, NULL, 0), -1);
>>> +
>>> +     /* Parent process should retrieve the data from the shared memory */
>>> +     ASSERT_EQ(memcmp(addr, STRING, sizeof(STRING)), 0);
>>>    }
>>>
>>>    TEST_HARNESS_MAIN
>>
> 



^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2025-09-02 21:35 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-25 14:57 [PATCH 0/8] Add selftests for mshare Yongting Lin
2025-08-25 14:57 ` [PATCH 1/8] mshare: Add selftests Yongting Lin
2025-08-25 14:57 ` [PATCH 2/8] mshare: selftests: Adding config fragment Yongting Lin
2025-08-25 14:57 ` [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem Yongting Lin
2025-08-25 14:57 ` [PATCH 4/8] mshare: selftests: Add test case shared memory Yongting Lin
2025-08-29  0:59   ` Anthony Yznaga
2025-09-01 12:50     ` [External] " Yongting Lin
2025-09-02 21:34       ` Anthony Yznaga
2025-08-25 14:57 ` [PATCH 5/8] mshare: selftests: Add test case ioctl unmap Yongting Lin
2025-08-25 14:57 ` [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup Yongting Lin
2025-08-25 14:57 ` [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory Yongting Lin
2025-08-25 14:57 ` [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP Yongting Lin
2025-08-29  1:04   ` Anthony Yznaga
2025-08-25 14:57 ` [PATCH 1/8] mshare: Add selftests Yongting Lin
2025-08-25 14:57 ` [PATCH 2/8] mshare: selftests: Adding config fragment Yongting Lin
2025-08-25 14:57 ` [PATCH 3/8] mshare: selftests: Add some helper function for mshare filesystem Yongting Lin
2025-08-25 14:57 ` [PATCH 4/8] mshare: selftests: Add test case shared memory Yongting Lin
2025-08-25 14:57 ` [PATCH 5/8] mshare: selftests: Add test case ioctl unmap Yongting Lin
2025-08-25 14:57 ` [PATCH 6/8] mshare: selftests: Add some helper functions for reading and controlling cgroup Yongting Lin
2025-08-25 14:57 ` [PATCH 7/8] mshare: selftests: Add test case to demostrate the swaping of mshare memory Yongting Lin
2025-08-25 14:57 ` [PATCH 8/8] mshare: selftests: Add test case to demostrate that mshare doesn't support THP Yongting Lin
2025-08-26 11:16 ` [PATCH 0/8] Add selftests for mshare Yongting Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).