[LTP] [PATCH v2 27/31] testcases: sysfs: Add sys_hugepages01

Cyril Hrubis <[email protected]>
Newsgroups it.linux.lists.ltp
Message-ID <[email protected]>
A test for /sys/kernel/mm/hugepages/hugepages-*/* files.

Signed-off-by: Cyril Hrubis <[email protected]>
---
 runtest/sysfs                                 |   1 +
 testcases/kernel/sysfs/kernel/mm/Makefile     |   7 +
 .../sysfs/kernel/mm/hugepages/.gitignore      |   1 +
 .../kernel/sysfs/kernel/mm/hugepages/Makefile |   7 +
 .../kernel/mm/hugepages/sys_hugepages01.c     | 133 ++++++++++++++++++
 5 files changed, 149 insertions(+)
 create mode 100644 testcases/kernel/sysfs/kernel/mm/Makefile
 create mode 100644 testcases/kernel/sysfs/kernel/mm/hugepages/.gitignore
 create mode 100644 testcases/kernel/sysfs/kernel/mm/hugepages/Makefile
 create mode 100644 testcases/kernel/sysfs/kernel/mm/hugepages/sys_hugepages01.c

diff --git a/runtest/sysfs b/runtest/sysfs
index 46593b82f..a81fbc12e 100644
--- a/runtest/sysfs
+++ b/runtest/sysfs
@@ -22,3 +22,4 @@ sys_net04 sys_net04
 sys_block_loop01 sys_block_loop01
 sys_block_queue01 sys_block_queue01
 sys_block_size01 sys_block_size01
+sys_hugepages01 sys_hugepages01
diff --git a/testcases/kernel/sysfs/kernel/mm/Makefile b/testcases/kernel/sysfs/kernel/mm/Makefile
new file mode 100644
index 000000000..9bc26552c
--- /dev/null
+++ b/testcases/kernel/sysfs/kernel/mm/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2026 Cyril Hrubis <[email protected]>
+
+top_srcdir		?= ../../../../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/kernel/sysfs/kernel/mm/hugepages/.gitignore b/testcases/kernel/sysfs/kernel/mm/hugepages/.gitignore
new file mode 100644
index 000000000..1c66028fb
--- /dev/null
+++ b/testcases/kernel/sysfs/kernel/mm/hugepages/.gitignore
@@ -0,0 +1 @@
+/sys_hugepages01
diff --git a/testcases/kernel/sysfs/kernel/mm/hugepages/Makefile b/testcases/kernel/sysfs/kernel/mm/hugepages/Makefile
new file mode 100644
index 000000000..781865569
--- /dev/null
+++ b/testcases/kernel/sysfs/kernel/mm/hugepages/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2026 Cyril Hrubis <[email protected]>
+
+top_srcdir		?= ../../../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/sysfs/kernel/mm/hugepages/sys_hugepages01.c b/testcases/kernel/sysfs/kernel/mm/hugepages/sys_hugepages01.c
new file mode 100644
index 000000000..13bcec3fc
--- /dev/null
+++ b/testcases/kernel/sysfs/kernel/mm/hugepages/sys_hugepages01.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <[email protected]>
+ */
+
+/*\
+ * Sanity checks for the hugepage pool attributes exported under
+ * /sys/kernel/mm/hugepages/.
+ *
+ * Each supported hugepage size has its own hugepages-<size>kB directory with a
+ * set of counters describing its pool. For each such directory the test
+ * verifies that:
+ *
+ * - the size encoded in the directory name is a power of two (in kB)
+ * - nr_hugepages, free_hugepages, resv_hugepages and surplus_hugepages are
+ *   all non-negative
+ * - free_hugepages <= nr_hugepages + surplus_hugepages (the free count cannot
+ *   exceed the total pool)
+ * - resv_hugepages <= free_hugepages (reserved pages are a subset of free)
+ *
+ * All checks skip gracefully with TCONF when a particular attribute is not
+ * present.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <limits.h>
+#include "tst_test.h"
+#include "tst_sysfs_assert.h"
+
+#define HUGEPAGES "/sys/kernel/mm/hugepages"
+
+static int read_count(const char *dir, const char *attr, long *val)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, sizeof(path), HUGEPAGES "/%s/%s", dir, attr);
+
+	if (access(path, F_OK))
+		return 1;
+
+	if (FILE_SCANF(path, "%ld", val))
+		return 1;
+
+	return 0;
+}
+
+static void check_size(const char *dir)
+{
+	long size;
+
+	if (sscanf(dir, "hugepages-%ldkB", &size) != 1) {
+		tst_res(TFAIL, "Malformed hugepage directory name '%s'", dir);
+		return;
+	}
+
+	if (size > 0 && !(size & (size - 1))) {
+		tst_res(TPASS, "%s: size %ld kB is a power of two", dir, size);
+	} else {
+		tst_res(TFAIL, "%s: size %ld kB is not a power of two",
+			dir, size);
+	}
+}
+
+static void check_counts(const char *dir)
+{
+	long nr, free, resv, surplus;
+
+	TST_SYSFS_ASSERT_RANGELL(0, LONG_MAX, HUGEPAGES "/%s/nr_hugepages", dir);
+	TST_SYSFS_ASSERT_RANGELL(0, LONG_MAX, HUGEPAGES "/%s/free_hugepages", dir);
+	TST_SYSFS_ASSERT_RANGELL(0, LONG_MAX, HUGEPAGES "/%s/resv_hugepages", dir);
+	TST_SYSFS_ASSERT_RANGELL(0, LONG_MAX,
+			       HUGEPAGES "/%s/surplus_hugepages", dir);
+
+	if (read_count(dir, "nr_hugepages", &nr) ||
+	    read_count(dir, "free_hugepages", &free) ||
+	    read_count(dir, "surplus_hugepages", &surplus))
+		return;
+
+	if (free <= nr + surplus) {
+		tst_res(TPASS,
+			"%s: free_hugepages (%ld) <= nr_hugepages (%ld) + surplus_hugepages (%ld)",
+			dir, free, nr, surplus);
+	} else {
+		tst_res(TFAIL,
+			"%s: free_hugepages (%ld) > nr_hugepages (%ld) + surplus_hugepages (%ld)",
+			dir, free, nr, surplus);
+	}
+
+	if (read_count(dir, "resv_hugepages", &resv))
+		return;
+
+	if (resv <= free) {
+		tst_res(TPASS, "%s: resv_hugepages (%ld) <= free_hugepages (%ld)",
+			dir, resv, free);
+	} else {
+		tst_res(TFAIL, "%s: resv_hugepages (%ld) > free_hugepages (%ld)",
+			dir, resv, free);
+	}
+}
+
+static void run(void)
+{
+	DIR *d;
+	struct dirent *ent;
+	int found = 0;
+
+	d = SAFE_OPENDIR(HUGEPAGES);
+
+	while ((ent = SAFE_READDIR(d))) {
+		if (strncmp(ent->d_name, "hugepages-", 10))
+			continue;
+
+		found = 1;
+		tst_res(TINFO, "Checking hugepage pool '%s'", ent->d_name);
+		check_size(ent->d_name);
+		check_counts(ent->d_name);
+	}
+
+	SAFE_CLOSEDIR(d);
+
+	if (!found)
+		tst_res(TCONF, "No hugepage pools found");
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.needs_kconfigs = (const char *const[]){
+		"CONFIG_HUGETLBFS=y",
+		NULL
+	},
+};
-- 
2.54.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.