* [LTP] [PATCH] Migrating the libhugetlbfs/testcases/quota.c - v2
@ 2026-04-04 12:11 Pavithra
2026-07-02 12:44 ` [LTP] " linuxtestproject.agent
2026-07-02 12:50 ` [LTP] [PATCH] " Andrea Cervesato via ltp
0 siblings, 2 replies; 3+ messages in thread
From: Pavithra @ 2026-04-04 12:11 UTC (permalink / raw)
To: ltp; +Cc: pavrampu
Test hugetlbfs quota accounting with filesystem size limits to check
for regressions in quota handling for MAP_PRIVATE and MAP_SHARED pages.
Signed-off-by: Pavithra <pavrampu@linux.ibm.com>
---
runtest/hugetlb | 1 +
testcases/kernel/mem/.gitignore | 1 +
.../kernel/mem/hugetlb/hugemmap/hugemmap33.c | 273 ++++++++++++++++++
3 files changed, 275 insertions(+)
create mode 100644 testcases/kernel/mem/hugetlb/hugemmap/hugemmap33.c
diff --git a/runtest/hugetlb b/runtest/hugetlb
index 0896d3c94..24fa717ec 100644
--- a/runtest/hugetlb
+++ b/runtest/hugetlb
@@ -35,6 +35,7 @@ hugemmap29 hugemmap29
hugemmap30 hugemmap30
hugemmap31 hugemmap31
hugemmap32 hugemmap32
+hugemmap33 hugemmap33
hugemmap34 hugemmap34
hugemmap05_1 hugemmap05 -m
hugemmap05_2 hugemmap05 -s
diff --git a/testcases/kernel/mem/.gitignore b/testcases/kernel/mem/.gitignore
index b4455de51..7f1bcd4e7 100644
--- a/testcases/kernel/mem/.gitignore
+++ b/testcases/kernel/mem/.gitignore
@@ -35,6 +35,7 @@
/hugetlb/hugemmap/hugemmap30
/hugetlb/hugemmap/hugemmap31
/hugetlb/hugemmap/hugemmap32
+/hugetlb/hugemmap/hugemmap33
/hugetlb/hugemmap/hugemmap34
/hugetlb/hugeshmat/hugeshmat01
/hugetlb/hugeshmat/hugeshmat02
diff --git a/testcases/kernel/mem/hugetlb/hugemmap/hugemmap33.c b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap33.c
new file mode 100644
index 000000000..75ecf5796
--- /dev/null
+++ b/testcases/kernel/mem/hugetlb/hugemmap/hugemmap33.c
@@ -0,0 +1,273 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ * Copyright (C) 2005-2007 David Gibson & Adam Litke, IBM Corporation.
+ * Copyright (c) Linux Test Project, 2024
+ * Copyright (C) 2025-2026 Naveed & Pavithra, IBM Corporation.
+ * Assisted with AI tools
+ */
+
+/*\
+ * Test hugetlbfs quota accounting with filesystem size limits.
+ *
+ * The number of global huge pages available to a mounted hugetlbfs filesystem
+ * can be limited using a quota mechanism by setting the size attribute at
+ * mount time. Older kernels did not properly handle quota accounting in a
+ * number of cases (e.g., for MAP_PRIVATE pages, and with MAP_SHARED reservation).
+ *
+ * This test replays some scenarios on a privately mounted filesystem with
+ * quota to check for regressions in hugetlbfs quota accounting.
+ */
+
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/vfs.h>
+#include <sys/statfs.h>
+#include <sys/mount.h>
+
+#include "hugetlb.h"
+
+#define MNTPOINT "hugetlbfs/"
+
+static long hpage_size;
+static int private_resv;
+static char quota_mnt[PATH_MAX];
+static int quota_mounted;
+
+/* map action flags */
+#define ACTION_COW 0x0001
+#define ACTION_TOUCH 0x0002
+
+/* Test result expectations */
+#define EXPECT_SUCCESS 0
+#define EXPECT_SIGNAL 1
+#define EXPECT_FAILURE 2
+
+static void verify_quota_stat(long tot, long free, long avail)
+{
+ struct statfs s;
+
+ SAFE_STATFS(quota_mnt, &s);
+
+ if ((long)s.f_blocks != tot || (long)s.f_bfree != free || (long)s.f_bavail != avail) {
+ tst_res(TFAIL,
+ "Bad quota counters: total=%li (expected %li), "
+ "free=%li (expected %li), avail=%li (expected %li)",
+ (long)s.f_blocks, tot, (long)s.f_bfree, free,
+ (long)s.f_bavail, avail);
+ }
+}
+
+static void do_map(unsigned long size, int mmap_flags, int action_flags)
+{
+ int fd;
+ char *a = MAP_FAILED, *b, *c = MAP_FAILED;
+ char path[PATH_MAX + 32];
+
+ snprintf(path, sizeof(path), "%s/test_file_%d", quota_mnt, getpid());
+ fd = SAFE_OPEN(path, O_CREAT | O_RDWR, 0600);
+ SAFE_UNLINK(path);
+
+ a = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, fd, 0);
+ if (a == MAP_FAILED) {
+ if (errno == ENOMEM || errno == ENOSPC) {
+ tst_res(TINFO | TERRNO, "mmap failed as expected due to quota");
+ goto cleanup_fd;
+ }
+ tst_brk(TBROK | TERRNO, "mmap failed unexpectedly");
+ }
+
+ if (action_flags & ACTION_TOUCH) {
+ for (b = a; b < a + size; b += hpage_size)
+ *b = 1;
+ }
+
+ if (action_flags & ACTION_COW) {
+ c = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (c == MAP_FAILED) {
+ if (errno == ENOMEM || errno == ENOSPC) {
+ tst_res(TINFO | TERRNO, "COW mapping failed as expected due to quota");
+ goto cleanup_a;
+ }
+ tst_brk(TBROK | TERRNO, "COW mapping failed unexpectedly");
+ }
+
+ if (*c != 1) {
+ tst_res(TINFO, "Data mismatch when setting up COW");
+ goto cleanup_c;
+ }
+ *c = 0;
+ SAFE_MUNMAP(c, size);
+ }
+
+ SAFE_MUNMAP(a, size);
+ SAFE_CLOSE(fd);
+ return;
+
+cleanup_c:
+ SAFE_MUNMAP(c, size);
+cleanup_a:
+ SAFE_MUNMAP(a, size);
+cleanup_fd:
+ SAFE_CLOSE(fd);
+ exit(1);
+}
+
+static void run_quota_test(int expected_result,
+ unsigned long size, int mmap_flags,
+ int action_flags)
+{
+ pid_t pid;
+ int status;
+ int actual_result;
+
+ pid = SAFE_FORK();
+ if (pid == 0) {
+ do_map(size, mmap_flags, action_flags);
+ exit(0);
+ }
+
+ SAFE_WAITPID(pid, &status, 0);
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) == 0)
+ actual_result = EXPECT_SUCCESS;
+ else
+ actual_result = EXPECT_FAILURE;
+ } else {
+ actual_result = EXPECT_SIGNAL;
+ }
+
+ if (actual_result != expected_result) {
+ static const char * const result_names[] = {"success", "signal", "failure"};
+
+ tst_res(TFAIL,
+ "Unexpected result: expected %s, got %s",
+ result_names[expected_result],
+ result_names[actual_result]);
+ } else {
+ tst_res(TPASS, "Quota test passed as expected");
+ }
+}
+
+static int kernel_has_private_reservations(void)
+{
+ int fd;
+ long t, f, r, s;
+ long nt, nf, nr, ns;
+ void *p;
+ char path[PATH_MAX];
+
+ t = SAFE_READ_MEMINFO(MEMINFO_HPAGE_TOTAL);
+ f = SAFE_READ_MEMINFO(MEMINFO_HPAGE_FREE);
+ r = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD);
+ s = SAFE_READ_MEMINFO(MEMINFO_HPAGE_SURP);
+
+ snprintf(path, sizeof(path), "%s/test_priv_resv", MNTPOINT);
+ fd = SAFE_OPEN(path, O_CREAT | O_RDWR, 0600);
+ SAFE_UNLINK(path);
+
+ p = SAFE_MMAP(NULL, hpage_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fd, 0);
+
+ nt = SAFE_READ_MEMINFO(MEMINFO_HPAGE_TOTAL);
+ nf = SAFE_READ_MEMINFO(MEMINFO_HPAGE_FREE);
+ nr = SAFE_READ_MEMINFO(MEMINFO_HPAGE_RSVD);
+ ns = SAFE_READ_MEMINFO(MEMINFO_HPAGE_SURP);
+
+ SAFE_MUNMAP(p, hpage_size);
+ SAFE_CLOSE(fd);
+
+ /* Check if reservation was created for private mapping */
+ if ((nt == t + 1) && (nf == f + 1) && (ns == s + 1) && (nr == r + 1))
+ return 1;
+ else if ((nt == t) && (nf == f) && (ns == s)) {
+ if (nr == r + 1)
+ return 1;
+ else if (nr == r)
+ return 0;
+ }
+
+ tst_brk(TCONF, "Unexpected counter state - "
+ "T:%li F:%li R:%li S:%li -> T:%li F:%li R:%li S:%li",
+ t, f, r, s, nt, nf, nr, ns);
+ return -1;
+}
+
+static void run_test(void)
+{
+ int bad_priv_resv = private_resv ? EXPECT_FAILURE : EXPECT_SIGNAL;
+
+ tst_res(TINFO, "Testing unused quota cleanup for untouched mappings");
+ run_quota_test(EXPECT_SUCCESS, hpage_size, MAP_PRIVATE, 0);
+ verify_quota_stat(1, 1, 1);
+ run_quota_test(EXPECT_SUCCESS, hpage_size, MAP_SHARED, 0);
+ verify_quota_stat(1, 1, 1);
+
+ tst_res(TINFO, "Testing page instantiation within quota limits");
+ run_quota_test(EXPECT_SUCCESS, hpage_size, MAP_PRIVATE, ACTION_TOUCH);
+ run_quota_test(EXPECT_SUCCESS, hpage_size, MAP_SHARED, ACTION_TOUCH);
+
+ tst_res(TINFO, "Testing page instantiation over quota");
+ run_quota_test(EXPECT_FAILURE, 2 * hpage_size, MAP_SHARED, ACTION_TOUCH);
+
+ tst_res(TINFO, "Testing private mapping quota check");
+ run_quota_test(bad_priv_resv, 2 * hpage_size, MAP_PRIVATE, ACTION_TOUCH);
+
+ tst_res(TINFO, "Testing COW over quota");
+ run_quota_test(bad_priv_resv, hpage_size, MAP_SHARED,
+ ACTION_TOUCH | ACTION_COW);
+ run_quota_test(bad_priv_resv, hpage_size, MAP_PRIVATE,
+ ACTION_TOUCH | ACTION_COW);
+
+ tst_res(TINFO, "Testing operations within quota after failures");
+ run_quota_test(EXPECT_SUCCESS, hpage_size, MAP_SHARED, ACTION_TOUCH);
+ run_quota_test(EXPECT_SUCCESS, hpage_size, MAP_PRIVATE, ACTION_TOUCH);
+}
+
+static void setup(void)
+{
+ char mount_opts[BUFSIZ];
+
+ hpage_size = tst_get_hugepage_size();
+
+ /* Create a quota-limited hugetlbfs mount */
+ snprintf(quota_mnt, sizeof(quota_mnt), "%s/quota_test", MNTPOINT);
+ SAFE_MKDIR(quota_mnt, 0755);
+
+ snprintf(mount_opts, sizeof(mount_opts), "size=%luK",
+ hpage_size / 1024);
+
+ if (mount("none", quota_mnt, "hugetlbfs", 0, mount_opts) == -1) {
+ if (errno == ENODEV)
+ tst_brk(TCONF, "hugetlbfs not supported");
+ tst_brk(TBROK | TERRNO, "mount() failed");
+ }
+ quota_mounted = 1;
+
+ tst_res(TINFO, "Mounted hugetlbfs with quota at %s (size=%luK)",
+ quota_mnt, hpage_size / 1024);
+
+ private_resv = kernel_has_private_reservations();
+ tst_res(TINFO, "Kernel %s private reservations",
+ private_resv ? "has" : "does not have");
+}
+
+static void cleanup(void)
+{
+ if (quota_mounted) {
+ SAFE_UMOUNT(quota_mnt);
+ SAFE_RMDIR(quota_mnt);
+ }
+}
+
+static struct tst_test test = {
+ .needs_root = 1,
+ .mntpoint = MNTPOINT,
+ .needs_hugetlbfs = 1,
+ .forks_child = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run_test,
+ .hugepages = {2, TST_NEEDS},
+};
--
2.53.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [LTP] Migrating the libhugetlbfs/testcases/quota.c - v2
2026-04-04 12:11 [LTP] [PATCH] Migrating the libhugetlbfs/testcases/quota.c - v2 Pavithra
@ 2026-07-02 12:44 ` linuxtestproject.agent
2026-07-02 12:50 ` [LTP] [PATCH] " Andrea Cervesato via ltp
1 sibling, 0 replies; 3+ messages in thread
From: linuxtestproject.agent @ 2026-07-02 12:44 UTC (permalink / raw)
To: Pavithra; +Cc: ltp
Hi Pavithra,
On Sat Apr 4 17:41:20 2026 +0530, Pavithra wrote:
> Migrating the libhugetlbfs/testcases/quota.c - v2
> Migrating the libhugetlbfs/testcases/quota.c - v2
The "- v2" suffix is a patch-revision marker that must be stripped from
the final commit subject before merging.
The subject should also follow the LTP convention of naming the
subsystem and what is being added, for example:
hugetlb/hugemmap: add hugemmap33 to test hugetlbfs quota accounting
> +/*\
> + * Test hugetlbfs quota accounting with filesystem size limits.
> + *
> + * The number of global huge pages available to a mounted hugetlbfs
> + * filesystem can be limited using a quota mechanism by setting the
> + * size attribute at mount time. Older kernels did not properly handle
> + * quota accounting in a number of cases (e.g., for MAP_PRIVATE pages,
> + * and with MAP_SHARED reservation).
> + *
> + * This test replays some scenarios on a privately mounted filesystem
> + * with quota to check for regressions in hugetlbfs quota accounting.
> + */
Ground Rule 4 requires that when a test sets .needs_root = 1, the
reason must be stated in the doc comment. The test mounts a second
hugetlbfs instance with a quota limit in setup(), which requires
CAP_SYS_ADMIN, but the description block is silent on this.
A sentence like the following should be added:
Root is required to mount the quota-limited hugetlbfs instance.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [LTP] [PATCH] Migrating the libhugetlbfs/testcases/quota.c - v2
2026-04-04 12:11 [LTP] [PATCH] Migrating the libhugetlbfs/testcases/quota.c - v2 Pavithra
2026-07-02 12:44 ` [LTP] " linuxtestproject.agent
@ 2026-07-02 12:50 ` Andrea Cervesato via ltp
1 sibling, 0 replies; 3+ messages in thread
From: Andrea Cervesato via ltp @ 2026-07-02 12:50 UTC (permalink / raw)
To: Pavithra; +Cc: pavrampu, ltp
Hi Pavithra,
I run the agent to all hugelibs patches to catch the most
obvious errors. I reviewed them and they seem positive, so feel
free to send a new version following the indications.
Please, don't append the version of the patch in the commit
message subject. All git commits have a specific section for it,
after the SOB and '---'
Regards,
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-02 12:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-04 12:11 [LTP] [PATCH] Migrating the libhugetlbfs/testcases/quota.c - v2 Pavithra
2026-07-02 12:44 ` [LTP] " linuxtestproject.agent
2026-07-02 12:50 ` [LTP] [PATCH] " Andrea Cervesato via ltp
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox