* [LTP] [PATCH] testcases: sysfs: Add sys_thp02
@ 2026-11-05 10:46 Xuewen Wang
2026-11-05 15:58 ` [LTP] " linuxtestproject.agent
0 siblings, 1 reply; 3+ messages in thread
From: Xuewen Wang @ 2026-11-05 10:46 UTC (permalink / raw)
To: ltp; +Cc: Xuewen Wang
From: Xuewen Wang <wangxuewen@kylinos.cn>
A test for the per-size mTHP attributes under
/sys/kernel/mm/transparent_hugepage/hugepages-*kB/. It iterates all
hugepages-<size>kB directories and checks the directory name structure,
the enabled/shmem_enabled choice files, the stats/ counters and that a
directory for the PMD-sized THP exists.
The set of mTHP attributes differs between kernel versions and
configurations, so missing attributes are skipped gracefully.
Tested on 6.6.160 (TCONF, no mTHP sizes) and 7.3.0-rc5, x86_64: 224/224
TPASS.
Signed-off-by: Xuewen Wang <wangxuewen@kylinos.cn>
---
runtest/sysfs | 1 +
.../kernel/mm/transparent_hugepage/.gitignore | 1 +
.../mm/transparent_hugepage/sys_thp02.c | 229 ++++++++++++++++++
3 files changed, 231 insertions(+)
create mode 100644 testcases/kernel/sysfs/kernel/mm/transparent_hugepage/sys_thp02.c
diff --git a/runtest/sysfs b/runtest/sysfs
index 5eb8f81f8..08763c21e 100644
--- a/runtest/sysfs
+++ b/runtest/sysfs
@@ -27,3 +27,4 @@ sys_hugepages02 sys_hugepages02
sys_ksm01 sys_ksm01
sys_mm_swap01 sys_mm_swap01
sys_thp01 sys_thp01
+sys_thp02 sys_thp02
diff --git a/testcases/kernel/sysfs/kernel/mm/transparent_hugepage/.gitignore b/testcases/kernel/sysfs/kernel/mm/transparent_hugepage/.gitignore
index bdb564dfe..ede87c4c1 100644
--- a/testcases/kernel/sysfs/kernel/mm/transparent_hugepage/.gitignore
+++ b/testcases/kernel/sysfs/kernel/mm/transparent_hugepage/.gitignore
@@ -1 +1,2 @@
/sys_thp01
+/sys_thp02
diff --git a/testcases/kernel/sysfs/kernel/mm/transparent_hugepage/sys_thp02.c b/testcases/kernel/sysfs/kernel/mm/transparent_hugepage/sys_thp02.c
new file mode 100644
index 000000000..144f11f79
--- /dev/null
+++ b/testcases/kernel/sysfs/kernel/mm/transparent_hugepage/sys_thp02.c
@@ -0,0 +1,229 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Xuewen Wang <wangxuewen@kylinos.cn>
+ */
+
+/*\
+ * Sanity checks for the multi-size Transparent HugePage (mTHP) attributes
+ * exported under /sys/kernel/mm/transparent_hugepage/hugepages-*kB/.
+ *
+ * Each THP size has its own hugepages-<size>kB directory with a per-size
+ * enabled flag and a stats/ subdirectory with a set of counters. For each
+ * such directory the test verifies that:
+ *
+ * - the size encoded in the directory name is a power of two, a power-of-two
+ * multiple of the base page size, and strictly larger than the base page
+ * size, or at least 4 pages for anonymous sizes
+ * - enabled selects one of always/inherit/madvise/never
+ * - shmem_enabled, if present, selects one of
+ * always/inherit/within_size/advise/never
+ * - the stats counters are non-negative
+ * - nr_anon_partially_mapped is not larger than nr_anon
+ *
+ * After all directories are checked the test verifies that a directory for
+ * the PMD-sized THP exists, since the kernel always creates it.
+ *
+ * Attributes which are not present on the running kernel are skipped
+ * gracefully, since the set of mTHP stats differs between kernel versions
+ * and configurations (e.g. CONFIG_SHMEM).
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <limits.h>
+#include "tst_test.h"
+#include "tst_sysfs_assert.h"
+#include "tst_path_defs.h"
+
+static const char *const enabled_allowed[] = {
+ "always", "inherit", "madvise", "never", NULL
+};
+
+static const char *const shmem_allowed[] = {
+ "always", "inherit", "within_size", "advise", "never", NULL
+};
+
+static const char *const any_stats[] = {
+ "split",
+ "split_failed",
+ "collapse_alloc",
+ "collapse_alloc_failed",
+ NULL
+};
+
+static const char *const anon_stats[] = {
+ "anon_fault_alloc",
+ "anon_fault_fallback",
+ "anon_fault_fallback_charge",
+ "split_deferred",
+ "nr_anon",
+ "nr_anon_partially_mapped",
+ "collapse_exceed_swap_pte",
+ "collapse_exceed_none_pte",
+ "collapse_exceed_shared_pte",
+ NULL
+};
+
+static const char *const swap_stats[] = {
+ "zswpout",
+ "swpin",
+ "swpin_fallback",
+ "swpin_fallback_charge",
+ "swpout",
+ "swpout_fallback",
+ NULL
+};
+
+static const char *const shmem_stats[] = {
+ "shmem_alloc",
+ "shmem_fallback",
+ "shmem_fallback_charge",
+ NULL
+};
+
+static long pagesize;
+static long pmd_kb;
+static int found_pmd;
+
+static void check_size(const char *dir, int is_anon)
+{
+ long size_kb, npages;
+
+ if (sscanf(dir, "hugepages-%ldkB", &size_kb) != 1) {
+ tst_res(TFAIL, "Malformed mTHP directory name '%s'", dir);
+ return;
+ }
+
+ if (size_kb <= 0 || size_kb & (size_kb - 1)) {
+ tst_res(TFAIL, "%s: size %ld kB is not a power of two", dir, size_kb);
+ return;
+ }
+
+ npages = size_kb * 1024 / pagesize;
+
+ if (npages < 2 || (npages & (npages - 1))) {
+ tst_res(TFAIL,
+ "%s: size %ld kB is not a power-of-two multiple of the page size",
+ dir, size_kb);
+ return;
+ }
+
+ if (is_anon && npages < 4) {
+ tst_res(TFAIL,
+ "%s: anonymous size %ld kB is smaller than 4 pages",
+ dir, size_kb);
+ return;
+ }
+
+ if (size_kb == pmd_kb)
+ found_pmd = 1;
+
+ tst_res(TPASS, "%s: size %ld kB is a valid mTHP size", dir, size_kb);
+}
+
+static void check_dir(const char *dir)
+{
+ size_t i;
+ int is_anon = tst_sysfs_exists(PATH_MM_THP "/%s/enabled", dir);
+ int is_shmem = tst_sysfs_exists(PATH_MM_THP "/%s/shmem_enabled", dir);
+
+ tst_res(TINFO, "Checking mTHP size '%s'", dir);
+
+ check_size(dir, is_anon);
+
+ if (is_anon)
+ TST_SYSFS_ASSERT_CHOICE(enabled_allowed, NULL, 0,
+ PATH_MM_THP "/%s/enabled", dir);
+
+ if (is_shmem)
+ TST_SYSFS_ASSERT_CHOICE(shmem_allowed, NULL, 0,
+ PATH_MM_THP "/%s/shmem_enabled", dir);
+
+ for (i = 0; any_stats[i]; i++) {
+ TST_SYSFS_ASSERT_RANGEUU_SILENT(0, ULONG_MAX,
+ PATH_MM_THP "/%s/stats/%s",
+ dir, any_stats[i]);
+ }
+
+ if (is_anon) {
+ for (i = 0; anon_stats[i]; i++) {
+ TST_SYSFS_ASSERT_RANGEUU_SILENT(0, ULONG_MAX,
+ PATH_MM_THP "/%s/stats/%s",
+ dir, anon_stats[i]);
+ }
+
+ TST_SYSFS_ASSERT_LE_SUFFIX_SILENT("/stats/nr_anon_partially_mapped",
+ "/stats/nr_anon",
+ PATH_MM_THP "/%s", dir);
+ }
+
+ if (is_shmem) {
+ for (i = 0; shmem_stats[i]; i++) {
+ TST_SYSFS_ASSERT_RANGEUU_SILENT(0, ULONG_MAX,
+ PATH_MM_THP "/%s/stats/%s",
+ dir, shmem_stats[i]);
+ }
+ }
+
+ for (i = 0; swap_stats[i]; i++) {
+ TST_SYSFS_ASSERT_RANGEUU_SILENT(0, ULONG_MAX,
+ PATH_MM_THP "/%s/stats/%s",
+ dir, swap_stats[i]);
+ }
+}
+
+static void setup(void)
+{
+ long pmd_size;
+
+ pagesize = getpagesize();
+
+ if (access(PATH_MM_THP "/hpage_pmd_size", F_OK))
+ tst_brk(TCONF, PATH_MM_THP "/hpage_pmd_size does not exist");
+
+ pmd_size = TST_SYSFS_READ_LI(PATH_MM_THP "/hpage_pmd_size");
+
+ if (pmd_size <= 0 || pmd_size % 1024)
+ tst_brk(TCONF, "Unexpected hpage_pmd_size %ld", pmd_size);
+
+ pmd_kb = pmd_size / 1024;
+}
+
+static void run(void)
+{
+ DIR *d;
+ struct dirent *ent;
+ int found = 0;
+
+ d = TST_SYSFS_TRY_OPENDIR(PATH_MM_THP);
+
+ while ((ent = SAFE_READDIR(d))) {
+ if (strncmp(ent->d_name, "hugepages-", 10))
+ continue;
+
+ found = 1;
+ check_dir(ent->d_name);
+ }
+
+ SAFE_CLOSEDIR(d);
+
+ if (!found) {
+ tst_res(TCONF, "No mTHP sizes found");
+ return;
+ }
+
+ if (found_pmd)
+ tst_res(TPASS, "hugepages-%ldkB directory is present", pmd_kb);
+ else
+ tst_res(TFAIL, "hugepages-%ldkB directory is missing", pmd_kb);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .needs_kconfigs = (const char *const[]){
+ "CONFIG_TRANSPARENT_HUGEPAGE=y",
+ NULL
+ },
+};
--
2.25.1
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [LTP] testcases: sysfs: Add sys_thp02
2026-11-05 10:46 [LTP] [PATCH] testcases: sysfs: Add sys_thp02 Xuewen Wang
@ 2026-11-05 15:58 ` linuxtestproject.agent
0 siblings, 0 replies; 3+ messages in thread
From: linuxtestproject.agent @ 2026-11-05 15:58 UTC (permalink / raw)
To: Xuewen Wang; +Cc: ltp
Hi Xuewen,
On Thu, Nov 5, 2026 at 6:46 PM, Xuewen Wang <wangxuewen@kylinos.cn> wrote:
> testcases: sysfs: Add sys_thp02
> +/*\
> + * Sanity checks for the multi-size Transparent HugePage (mTHP) attributes
> + * exported under /sys/kernel/mm/transparent_hugepage/hugepages-*kB/.
The unescaped '*kB' after '-' in the reStructuredText doc comment is parsed
as an unclosed emphasis start-string. Use 'hugepages-<size>kB/' (matching the
next paragraph) or wrap the path in double backticks.
> + if (is_anon)
> + TST_SYSFS_ASSERT_CHOICE(enabled_allowed, NULL, 0,
> + PATH_MM_THP "/%s/enabled", dir);
> +
> + if (is_shmem)
> + TST_SYSFS_ASSERT_CHOICE(shmem_allowed, NULL, 0,
> + PATH_MM_THP "/%s/shmem_enabled", dir);
> +
> + for (i = 0; any_stats[i]; i++) {
> + TST_SYSFS_ASSERT_RANGEUU_SILENT(0, ULONG_MAX,
> + PATH_MM_THP "/%s/stats/%s",
> + dir, any_stats[i]);
> + }
> +
> + if (is_anon) {
These two 'if' statements have multi-line bodies without curly braces and
duplicate the 'if (is_anon)' and 'if (is_shmem)' blocks immediately below.
Move the TST_SYSFS_ASSERT_CHOICE() calls into the braced 'if (is_anon)' and
'if (is_shmem)' blocks below (or add curly braces).
> +static void run(void)
> +{
> + DIR *d;
> + struct dirent *ent;
> + int found = 0;
> +
> + d = TST_SYSFS_TRY_OPENDIR(PATH_MM_THP);
'found_pmd' is a file-scope static variable that is set to 1 in check_size()
and never reset at the start of run(), so it stays set across '-i'
iterations. Reset 'found_pmd = 0;' at the beginning of run().
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] testcases: sysfs: Add sys_thp02
2026-11-06 3:22 [LTP] [PATCH v2] " Xuewen Wang
@ 2026-11-06 11:34 ` linuxtestproject.agent
0 siblings, 0 replies; 3+ messages in thread
From: linuxtestproject.agent @ 2026-11-06 11:34 UTC (permalink / raw)
To: Xuewen Wang; +Cc: ltp
Hi Xuewen,
On Fri Nov 6 11:22:51 2026 +0800, Xuewen Wang <wangxuewen@kylinos.cn> wrote:
> testcases: sysfs: Add sys_thp02
Verdict - Reviewed
---
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
end of thread, other threads:[~2026-11-06 11:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-05 10:46 [LTP] [PATCH] testcases: sysfs: Add sys_thp02 Xuewen Wang
2026-11-05 15:58 ` [LTP] " linuxtestproject.agent
-- strict thread matches above, loose matches on Subject: below --
2026-11-06 3:22 [LTP] [PATCH v2] " Xuewen Wang
2026-11-06 11:34 ` [LTP] " linuxtestproject.agent
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.