From: Samir Mulani <samir@linux.ibm.com>
To: ltp@lists.linux.it
Cc: liwang@redhat.com, Samir Mulani <samir@linux.ibm.com>
Subject: [LTP] [PATCH v5] hugetlb/hugeshmat: Add hugeshmat06 migrated from libhugetlbfs shm-perms
Date: Thu, 20 Aug 2026 18:25:51 +0530 [thread overview]
Message-ID: <20260820125552.47435-1-samir@linux.ibm.com> (raw)
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
next reply other threads:[~2026-08-20 18:27 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 12:55 Samir Mulani [this message]
2026-08-20 18:40 ` [LTP] hugetlb/hugeshmat: Add hugeshmat06 migrated from libhugetlbfs shm-perms linuxtestproject.agent
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260820125552.47435-1-samir@linux.ibm.com \
--to=samir@linux.ibm.com \
--cc=liwang@redhat.com \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.