Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH v5] hugetlb/hugeshmat: Add hugeshmat06 migrated from libhugetlbfs shm-perms
@ 2026-08-20 12:55 Samir Mulani
  2026-08-20 18:40 ` [LTP] " linuxtestproject.agent
  0 siblings, 1 reply; 2+ messages in thread
From: Samir Mulani @ 2026-08-20 12:55 UTC (permalink / raw)
  To: ltp; +Cc: liwang, Samir Mulani

Test shared memory behavior when multiple processes attach to a
hugepage-backed segment with different permissions.

At one point, reservation accounting of free hugepages between the
parent and child processes may become inconsistent during memory
operations. The parent creates a shared memory segment backed by
4 hugepages (permission 0640), attaches it read-write, initialises
each hugepage with a pattern (0x55), then detaches. Child processes
are forked in a loop, each reattaching the segment read-only via
SHM_RDONLY, verifying the data pattern, detaching, and exiting.

If the reservation accounting leaks, repeated read-only attaches
will exhaust the hugepage pool and shmat() will fail. The test
uses raw shmat() in each child and reports this failure as TFAIL.

Signed-off-by: Samir Mulani <samir@linux.ibm.com>
---
Changes in v5:
 1. Use raw shmat() instead of SAFE_SHMAT() and report pool
    exhaustion as TFAIL. HugetlbPages from /proc/<pid>/status
    only tracks mapped pages and can return zero after shmdt()
    even when resv_huge_pages is still leaked, so it is not a
    reliable oracle for this regression. [LTP AI Reviewer]
 2. Remove get_proc_hugetlb_kb() helper and the HugetlbPages
    check as they are no longer needed. [LTP AI Reviewer]
 3. Use IPC_PRIVATE instead of a fixed SEGMENT_KEY to avoid
    accidentally reusing or destroying a pre-existing segment.
    [LTP AI Reviewer]
 4. Drop the deprecated [Description] tag from the /*\ block.
    [LTP AI Reviewer]

Link: https://lore.kernel.org/ltp/49b1dbd9-4c51-414a-806c-1d5cc6b5e1c7@linux.ibm.com/ # v3 
Link: https://lore.kernel.org/ltp/20260820042516.46631-1-samir@linux.ibm.com/ # v4

 runtest/hugetlb                               |   1 +
 testcases/kernel/mem/.gitignore               |   1 +
 .../mem/hugetlb/hugeshmat/hugeshmat06.c       | 152 ++++++++++++++++++
 3 files changed, 154 insertions(+)
 create mode 100644 testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat06.c

diff --git a/runtest/hugetlb b/runtest/hugetlb
index 6b35c1f42..1eb5c3339 100644
--- a/runtest/hugetlb
+++ b/runtest/hugetlb
@@ -49,6 +49,7 @@ hugeshmat02 hugeshmat02 -i 5
 hugeshmat03 hugeshmat03 -i 5
 hugeshmat04 hugeshmat04 -i 5
 hugeshmat05 hugeshmat05 -i 5
+hugeshmat06 hugeshmat06 -i 5
 
 hugeshmctl01 hugeshmctl01 -i 5
 hugeshmctl02 hugeshmctl02 -i 5
diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore
index e63a6dde7..704f89d5e 100644
--- a/testcases/kernel/mem/.gitignore
+++ b/testcases/kernel/mem/.gitignore
@@ -45,6 +45,7 @@
 /hugetlb/hugeshmat/hugeshmat03
 /hugetlb/hugeshmat/hugeshmat04
 /hugetlb/hugeshmat/hugeshmat05
+/hugetlb/hugeshmat/hugeshmat06
 /hugetlb/hugeshmctl/hugeshmctl01
 /hugetlb/hugeshmctl/hugeshmctl02
 /hugetlb/hugeshmctl/hugeshmctl03
diff --git a/testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat06.c b/testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat06.c
new file mode 100644
index 000000000..440d85672
--- /dev/null
+++ b/testcases/kernel/mem/hugetlb/hugeshmat/hugeshmat06.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2005-2006 IBM Corporation.
+ * Author: David Gibson & Adam Litke
+ */
+
+/*\
+ * Tests shared memory behavior when multiple processes attach to a
+ * hugepage-backed segment with different permissions.
+ *
+ * The parent creates a shared memory segment (permission 0640) backed by
+ * hugepages, attaches it read-write, initialises each hugepage with a
+ * pattern (0x55), then detaches.  A number of child processes are then
+ * forked; each child reattaches the segment read-only (SHM_RDONLY),
+ * verifies the expected pattern in every hugepage, detaches, and exits.
+ *
+ * The original libhugetlbfs shm-perms regression leaked resv_huge_pages
+ * on each read-only attach, eventually exhausting the hugepage reservation
+ * pool.  This is detected by using raw shmat() in each child so that a
+ * pool-exhaustion failure is reported as TFAIL rather than TBROK.
+ */
+
+#include "hugetlb.h"
+#include "tst_safe_sysv_ipc.h"
+
+#define MNTPOINT	"hugetlbfs/"
+#define HPAGES_IN_SEG	4
+#define PATTERN		0x55
+#define MAX_CHILDREN	128
+
+static int global_shmid = -1;
+static long hpage_size;
+static long segment_size;
+
+static void setup(void)
+{
+	int shmid;
+	char *p;
+	int i;
+
+	hpage_size = tst_get_hugepage_size();
+	if (!hpage_size)
+		tst_brk(TCONF, "Hugepages are not supported");
+
+	segment_size = HPAGES_IN_SEG * hpage_size;
+
+	/* Create the hugepage SHM segment with 0640 permissions */
+	shmid = SAFE_SHMGET(IPC_PRIVATE, segment_size,
+			    IPC_CREAT | SHM_HUGETLB | 0640);
+	global_shmid = shmid;
+
+	/* Attach read-write, write a known pattern into each hugepage */
+	p = SAFE_SHMAT(shmid, NULL, 0);
+
+	for (i = 0; i < HPAGES_IN_SEG; i++)
+		memset(p + (i * hpage_size), PATTERN, hpage_size);
+
+	SAFE_SHMDT((const void *)p);
+}
+
+static void cleanup(void)
+{
+	if (global_shmid >= 0)
+		SAFE_SHMCTL(global_shmid, IPC_RMID, NULL);
+}
+
+static void run_test(void)
+{
+	int i, iterations;
+	pid_t pid;
+
+	/*
+	 * Number of attach/detach cycles to exercise reservation accounting.
+	 * Use tst_hugepages (reserved by the framework) but cap at
+	 * MAX_CHILDREN to avoid spawning an unreasonable number of children
+	 * on large-memory machines.
+	 */
+	iterations = MIN((long)tst_hugepages, (long)MAX_CHILDREN);
+
+	tst_res(TINFO, "Running %d child attach/detach iterations", iterations);
+
+	for (i = 0; i < iterations; i++) {
+		pid = SAFE_FORK();
+		if (pid == 0) {
+			/* ---- child ---- */
+			char *shmaddr;
+			int j;
+
+			/*
+			 * Use raw shmat() instead of SAFE_SHMAT() so that a
+			 * failure caused by resv_huge_pages exhaustion is
+			 * reported as TFAIL, not TBROK.
+			 */
+			shmaddr = shmat(global_shmid, NULL, SHM_RDONLY);
+			if (shmaddr == (void *)-1) {
+				tst_res(TFAIL | TERRNO,
+					"Child %d: shmat() failed, hugepage reservation pool may be exhausted",
+					getpid());
+				exit(EXIT_FAILURE);
+			}
+
+			tst_res(TINFO, "Child %d attached segment successfully",
+				getpid());
+
+			/* Verify the pattern written by the parent */
+			for (j = 0; j < HPAGES_IN_SEG; j++) {
+				unsigned char val =
+					*((unsigned char *)shmaddr +
+					  (j * hpage_size));
+
+				if (val != PATTERN) {
+					tst_res(TFAIL,
+						"Child %d: hugepage[%d] data mismatch: got 0x%02x, expected 0x%02x",
+						getpid(), j, (unsigned int)val, PATTERN);
+					SAFE_SHMDT((const void *)shmaddr);
+					exit(EXIT_FAILURE);
+				}
+			}
+
+			SAFE_SHMDT((const void *)shmaddr);
+			exit(EXIT_SUCCESS);
+		}
+	}
+
+	/*
+	 * Wait for all children.  tst_reap_children() calls tst_brk(TBROK)
+	 * if any child exited non-zero, so a TFAIL inside a child is
+	 * automatically promoted to a test-level failure here.
+	 */
+	tst_reap_children();
+
+	tst_res(TPASS,
+		"All %d children attached read-only and verified reservation accounting",
+		iterations);
+}
+
+static struct tst_test test = {
+	.needs_root	 = 1,
+	.mntpoint	 = MNTPOINT,
+	.needs_hugetlbfs = 1,
+	.needs_tmpdir	 = 1,
+	.forks_child	 = 1,
+	.setup		 = setup,
+	.cleanup	 = cleanup,
+	.test_all	 = run_test,
+	/*
+	 * Request HPAGES_IN_SEG hugepages; that is all the test needs.
+	 * TST_NEEDS means the test is skipped if the kernel cannot
+	 * provide them.
+	 */
+	.hugepages	 = {HPAGES_IN_SEG, TST_NEEDS},
+};
-- 
2.52.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

end of thread, other threads:[~2026-08-20 18:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-20 12:55 [LTP] [PATCH v5] hugetlb/hugeshmat: Add hugeshmat06 migrated from libhugetlbfs shm-perms Samir Mulani
2026-08-20 18:40 ` [LTP] " linuxtestproject.agent

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox