Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/5] selftests/mm: Handle unsupported and transient test conditions
@ 2026-07-27  9:52 Muhammad Usama Anjum
  2026-07-27  9:52 ` [PATCH v3 1/5] selftests/mm: skip COW tmpfile cases when fallocate() is unsupported Muhammad Usama Anjum
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Muhammad Usama Anjum @ 2026-07-27  9:52 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Miaohe Lin, Naoya Horiguchi, linux-mm,
	linux-kselftest, linux-kernel
  Cc: Muhammad Usama Anjum

Several MM selftests report failures when the test environment lacks
an underlying prerequisite, such as fallocate() support, MADV_REMOVE,
local page-cache semantics, or swap.

This series converts those unsupported cases to SKIP while preserving
failures for unexpected errors. It also allows migration tests to retry
transient move_pages() failures.

Tested on an arm64 Ampere system using an NFS root filesystem. The MM
selftest run completed without failures or errors. Also verified on
x86_64 to ensure the changes do not cause unexpected errors.

Changes since v2:
- Explain why the hard dirty-page variant is skipped on NFS.
- Return -2 when the page is not on the target node.

Changes since v1:
- Print swapout diagnostics before reporting no-swap skips.
- Limit the NFS skip to the hard dirty-page variant.
- Retry per-page failures for the full runtime.
- Verify that both alternating NUMA targets are reached.

Muhammad Usama Anjum (5):
  selftests/mm: skip COW tmpfile cases when fallocate() is unsupported
  selftests/mm: skip guard hole-punch test if MADV_REMOVE is unsupported
  selftests/mm: skip khugepaged swap tests without swap
  selftests/mm: skip hard dirty page-cache test on NFS
  selftests/mm: retry migration failures for the full runtime

 tools/testing/selftests/mm/cow.c            |  9 +++--
 tools/testing/selftests/mm/guard-regions.c  | 10 ++++--
 tools/testing/selftests/mm/khugepaged.c     | 38 +++++++++++++++++++--
 tools/testing/selftests/mm/memory-failure.c | 14 ++++++--
 tools/testing/selftests/mm/migration.c      | 37 +++++++++++---------
 5 files changed, 82 insertions(+), 26 deletions(-)

-- 
2.47.3



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

* [PATCH v3 1/5] selftests/mm: skip COW tmpfile cases when fallocate() is unsupported
  2026-07-27  9:52 [PATCH v3 0/5] selftests/mm: Handle unsupported and transient test conditions Muhammad Usama Anjum
@ 2026-07-27  9:52 ` Muhammad Usama Anjum
  2026-07-27 16:45   ` Usama Arif
  2026-07-27  9:52 ` [PATCH v3 2/5] selftests/mm: skip guard hole-punch test if MADV_REMOVE " Muhammad Usama Anjum
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Muhammad Usama Anjum @ 2026-07-27  9:52 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Miaohe Lin, Naoya Horiguchi, linux-mm,
	linux-kselftest, linux-kernel
  Cc: Muhammad Usama Anjum, Sarthak Sharma

The tmpfile-backed COW cases allocate a one-page file with fallocate()
before exercising private and shared mappings.  When the filesystem
backing tmpfile() does not implement fallocate(), setup fails with
EOPNOTSUPP and no COW behavior is exercised.

This occurs when the temporary directory resides on a filesystem with
limited allocation support, such as NFSv3.  Reporting a failure adds
noise because the test prerequisite is absent rather than the COW
implementation being broken.

Report EOPNOTSUPP as a skip.  Continue treating every other fallocate()
error as a failure so unexpected setup regressions remain visible.

Tested-by: Sarthak Sharma <sarthak.sharma@arm.com>
Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
---
 tools/testing/selftests/mm/cow.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
index 0c627ea89ff7b..c1b8920e29342 100644
--- a/tools/testing/selftests/mm/cow.c
+++ b/tools/testing/selftests/mm/cow.c
@@ -1718,8 +1718,13 @@ static void run_with_tmpfile(non_anon_test_fn fn, const char *desc)
 
 	/* File consists of a single page filled with zeroes. */
 	if (fallocate(fd, 0, 0, pagesize)) {
-		ksft_perror("fallocate() failed");
-		log_test_result(KSFT_FAIL);
+		if (errno == EOPNOTSUPP) {
+			ksft_print_msg("fallocate() not supported by filesystem\n");
+			log_test_result(KSFT_SKIP);
+		} else {
+			ksft_perror("fallocate() failed");
+			log_test_result(KSFT_FAIL);
+		}
 		goto close;
 	}
 
-- 
2.47.3



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

* [PATCH v3 2/5] selftests/mm: skip guard hole-punch test if MADV_REMOVE is unsupported
  2026-07-27  9:52 [PATCH v3 0/5] selftests/mm: Handle unsupported and transient test conditions Muhammad Usama Anjum
  2026-07-27  9:52 ` [PATCH v3 1/5] selftests/mm: skip COW tmpfile cases when fallocate() is unsupported Muhammad Usama Anjum
@ 2026-07-27  9:52 ` Muhammad Usama Anjum
  2026-07-27 16:52   ` Usama Arif
  2026-07-27  9:52 ` [PATCH v3 3/5] selftests/mm: skip khugepaged swap tests without swap Muhammad Usama Anjum
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Muhammad Usama Anjum @ 2026-07-27  9:52 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Miaohe Lin, Naoya Horiguchi, linux-mm,
	linux-kselftest, linux-kernel
  Cc: Muhammad Usama Anjum, Sarthak Sharma

The hole_punch case verifies that guard regions survive MADV_REMOVE and
that the backing range is punched out.  MADV_REMOVE delegates the hole
punch to the backing filesystem, which may reject the operation with
EOPNOTSUPP.

That result means the test cannot establish the state whose guard
semantics it intends to validate.  Treating the missing filesystem
capability as a guard-region failure creates a false regression.

Unmap the range and skip only when MADV_REMOVE fails with EOPNOTSUPP.
Preserve the assertion for all other errors so failures on supported
configurations remain visible.

Tested-by: Sarthak Sharma <sarthak.sharma@arm.com>
Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
---
 tools/testing/selftests/mm/guard-regions.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c
index b21df3040b1c7..5c8ec3ca75d7d 100644
--- a/tools/testing/selftests/mm/guard-regions.c
+++ b/tools/testing/selftests/mm/guard-regions.c
@@ -1912,7 +1912,7 @@ TEST_F(guard_regions, hole_punch)
 {
 	const unsigned long page_size = self->page_size;
 	char *ptr;
-	int i;
+	int i, ret;
 
 	if (variant->backing == ANON_BACKED)
 		SKIP(return, "Truncation test specific to file-backed");
@@ -1944,8 +1944,12 @@ TEST_F(guard_regions, hole_punch)
 	}
 
 	/* Now hole punch the guarded region. */
-	ASSERT_EQ(madvise(&ptr[3 * page_size], 4 * page_size,
-			  MADV_REMOVE), 0);
+	ret = madvise(&ptr[3 * page_size], 4 * page_size, MADV_REMOVE);
+	if (ret == -1 && errno == EOPNOTSUPP) {
+		ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
+		SKIP(return, "MADV_REMOVE not supported by filesystem");
+	}
+	ASSERT_EQ(ret, 0);
 
 	/* Ensure guard regions remain. */
 	for (i = 0; i < 10; i++) {
-- 
2.47.3



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

* [PATCH v3 3/5] selftests/mm: skip khugepaged swap tests without swap
  2026-07-27  9:52 [PATCH v3 0/5] selftests/mm: Handle unsupported and transient test conditions Muhammad Usama Anjum
  2026-07-27  9:52 ` [PATCH v3 1/5] selftests/mm: skip COW tmpfile cases when fallocate() is unsupported Muhammad Usama Anjum
  2026-07-27  9:52 ` [PATCH v3 2/5] selftests/mm: skip guard hole-punch test if MADV_REMOVE " Muhammad Usama Anjum
@ 2026-07-27  9:52 ` Muhammad Usama Anjum
  2026-07-27 17:18   ` Usama Arif
  2026-07-27  9:52 ` [PATCH v3 4/5] selftests/mm: skip hard dirty page-cache test on NFS Muhammad Usama Anjum
  2026-07-27  9:52 ` [PATCH v3 5/5] selftests/mm: retry migration failures for the full runtime Muhammad Usama Anjum
  4 siblings, 1 reply; 9+ messages in thread
From: Muhammad Usama Anjum @ 2026-07-27  9:52 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Miaohe Lin, Naoya Horiguchi, linux-mm,
	linux-kselftest, linux-kernel
  Cc: Muhammad Usama Anjum

collapse_swapin_single_pte and collapse_max_ptes_swap require
MADV_PAGEOUT to replace anonymous pages with swap entries. On swapless
systems there is no backing store with which to create those entries,
so check_swap() reports missing setup rather than broken khugepaged
behavior.

Swapless configurations are common on Android and other constrained
test devices. Failing these cases obscures actionable results from the
rest of the khugepaged suite.

Check /proc/swaps before either swap-dependent case and skip when no
active swap area exists. With swap present, retain the existing
MADV_PAGEOUT and swap-entry assertions unchanged.

Print each existing swapout diagnostic before the prerequisite check
so skip() completes a KTAP diagnostic line instead of emitting an
unprefixed message.

Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
---
Changes since v1:
- Print swapout diagnostics before reporting no-swap skips.
---
 tools/testing/selftests/mm/khugepaged.c | 38 +++++++++++++++++++++++--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
index 10e8dedcb087d..54e888eb48bbc 100644
--- a/tools/testing/selftests/mm/khugepaged.c
+++ b/tools/testing/selftests/mm/khugepaged.c
@@ -100,6 +100,28 @@ static void skip(const char *msg)
 	exit_status = KSFT_SKIP;
 }
 
+static bool is_swap_enabled(void)
+{
+	char buf[MAX_LINE_LENGTH];
+	FILE *file;
+	bool enabled = false;
+
+	file = fopen("/proc/swaps", "r");
+	if (!file)
+		return false;
+
+	if (!fgets(buf, sizeof(buf), file))
+		goto out;
+
+	/* Check for first active swap entry. */
+	if (fgets(buf, sizeof(buf), file))
+		enabled = true;
+
+out:
+	fclose(file);
+	return enabled;
+}
+
 static void save_settings(void)
 {
 	ksft_print_msg("Save THP and khugepaged settings...");
@@ -734,10 +756,16 @@ static void collapse_swapin_single_pte(struct collapse_context *c, struct mem_op
 {
 	void *p;
 
+	ksft_print_msg("Swapout one page...");
+	if (!is_swap_enabled()) {
+		skip("No active swap");
+		ksft_test_result_report(exit_status, "%s\n", __func__);
+		return;
+	}
+
 	p = ops->setup_area(1);
 	ops->fault(p, 0, hpage_pmd_size);
 
-	ksft_print_msg("Swapout one page...");
 	if (madvise(p, page_size, MADV_PAGEOUT))
 		ksft_exit_fail_perror("madvise(MADV_PAGEOUT)");
 	if (check_swap(p, page_size)) {
@@ -760,10 +788,16 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o
 	int max_ptes_swap = thp_read_num("khugepaged/max_ptes_swap");
 	void *p;
 
+	ksft_print_msg("Swapout %d of %d pages...", max_ptes_swap + 1, hpage_pmd_nr);
+	if (!is_swap_enabled()) {
+		skip("No active swap");
+		ksft_test_result_report(exit_status, "%s\n", __func__);
+		return;
+	}
+
 	p = ops->setup_area(1);
 	ops->fault(p, 0, hpage_pmd_size);
 
-	ksft_print_msg("Swapout %d of %d pages...", max_ptes_swap + 1, hpage_pmd_nr);
 	if (madvise(p, (max_ptes_swap + 1) * page_size, MADV_PAGEOUT))
 		ksft_exit_fail_perror("madvise(MADV_PAGEOUT)");
 	if (check_swap(p, (max_ptes_swap + 1) * page_size)) {
-- 
2.47.3



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

* [PATCH v3 4/5] selftests/mm: skip hard dirty page-cache test on NFS
  2026-07-27  9:52 [PATCH v3 0/5] selftests/mm: Handle unsupported and transient test conditions Muhammad Usama Anjum
                   ` (2 preceding siblings ...)
  2026-07-27  9:52 ` [PATCH v3 3/5] selftests/mm: skip khugepaged swap tests without swap Muhammad Usama Anjum
@ 2026-07-27  9:52 ` Muhammad Usama Anjum
  2026-07-27  9:52 ` [PATCH v3 5/5] selftests/mm: retry migration failures for the full runtime Muhammad Usama Anjum
  4 siblings, 0 replies; 9+ messages in thread
From: Muhammad Usama Anjum @ 2026-07-27  9:52 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Miaohe Lin, Naoya Horiguchi, linux-mm,
	linux-kselftest, linux-kernel
  Cc: Muhammad Usama Anjum

The hard dirty_pagecache variant uses MADV_HWPOISON to exercise recovery
of a dirty file-backed page. The recovery path records -EIO in the
address_space mapping, which NFS later reports when the test closes the
file. This makes the test fail after the hwpoison checks have completed.

Skip this variant when the test file is on NFS. Keep the hard clean-page
and both soft-offline variants enabled because they use folio removal,
invalidation, or migration rather than recording a delayed writeback
error.

The unsupported-filesystem path in clean_pagecache() also returns
without closing the opened test file. Close the descriptor before
skipping there and in dirty_pagecache().

Reviewed-by: Miaohe Lin <linmiaohe@huawei.com>
Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
---
Changes since v2:
- Explain why the hard dirty-page variant is skipped on NFS.

Changes since v1:
- Limit the NFS skip to the hard dirty-page variant.
---
 tools/testing/selftests/mm/memory-failure.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/mm/memory-failure.c b/tools/testing/selftests/mm/memory-failure.c
index 032ed952057c6..5d00aab31f9b5 100644
--- a/tools/testing/selftests/mm/memory-failure.c
+++ b/tools/testing/selftests/mm/memory-failure.c
@@ -283,8 +283,10 @@ TEST_F(memory_failure, clean_pagecache)
 	if (fd < 0)
 		SKIP(return, "failed to open test file.\n");
 	fs_type = get_fs_type(fd);
-	if (!fs_type || fs_type == TMPFS_MAGIC)
+	if (!fs_type || fs_type == TMPFS_MAGIC) {
+		close(fd);
 		SKIP(return, "unsupported filesystem :%x\n", fs_type);
+	}
 
 	addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE,
 		    MAP_SHARED, fd, 0);
@@ -325,8 +327,16 @@ TEST_F(memory_failure, dirty_pagecache)
 	if (fd < 0)
 		SKIP(return, "failed to open test file.\n");
 	fs_type = get_fs_type(fd);
-	if (!fs_type || fs_type == TMPFS_MAGIC)
+	/*
+	 * MADV_HARD poisoning of dirty page-cache data records an expected
+	 * -EIO in the file mapping. NFS reports this error on close(), so
+	 * skip this variant.
+	 */
+	if (!fs_type || fs_type == TMPFS_MAGIC ||
+	    (fs_type == NFS_SUPER_MAGIC && variant->type == MADV_HARD)) {
+		close(fd);
 		SKIP(return, "unsupported filesystem :%x\n", fs_type);
+	}
 
 	addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE,
 		    MAP_SHARED, fd, 0);
-- 
2.47.3



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

* [PATCH v3 5/5] selftests/mm: retry migration failures for the full runtime
  2026-07-27  9:52 [PATCH v3 0/5] selftests/mm: Handle unsupported and transient test conditions Muhammad Usama Anjum
                   ` (3 preceding siblings ...)
  2026-07-27  9:52 ` [PATCH v3 4/5] selftests/mm: skip hard dirty page-cache test on NFS Muhammad Usama Anjum
@ 2026-07-27  9:52 ` Muhammad Usama Anjum
  4 siblings, 0 replies; 9+ messages in thread
From: Muhammad Usama Anjum @ 2026-07-27  9:52 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Usama Arif, Miaohe Lin, Naoya Horiguchi, linux-mm,
	linux-kselftest, linux-kernel
  Cc: Muhammad Usama Anjum

move_pages() is best effort and can temporarily fail when concurrent
faults race with page unmapping. A busy shared-anon workload can exhaust
the current 100 retries long before the intended 20-second runtime and
produce a false failure.

Use the full runtime as the retry window. Since the initial page location
is unknown, require it to reach both alternating NUMA targets to confirm
that cross-node migration made progress despite transient contention.

Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
---
Changes since v2:
- Return -2 when the page is not on the target node.

Changes since v1:
- Retry per-page failures for the full runtime
- Verify that both alternating NUMA targets are reached
---
 tools/testing/selftests/mm/migration.c | 37 ++++++++++++++------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/tools/testing/selftests/mm/migration.c b/tools/testing/selftests/mm/migration.c
index 29f7492453d43..f19d53c695764 100644
--- a/tools/testing/selftests/mm/migration.c
+++ b/tools/testing/selftests/mm/migration.c
@@ -7,7 +7,7 @@
 #include "kselftest_harness.h"
 #include "hugepage_settings.h"
 
-#include <strings.h>
+#include <string.h>
 #include <pthread.h>
 #include <numa.h>
 #include <numaif.h>
@@ -20,7 +20,6 @@
 
 #define TWOMEG		(2<<20)
 #define RUNTIME		(20)
-#define MAX_RETRIES	100
 #define ALIGN(x, a)	(((x) + (a - 1)) & (~((a) - 1)))
 
 HUGETLB_SETUP_DEFAULT_PAGES(1)
@@ -110,7 +109,7 @@ int migrate(uint64_t *ptr, int n1, int n2)
 	int ret, tmp;
 	int status = 0;
 	struct timespec ts1, ts2;
-	int failures = 0;
+	int success = 0;
 
 	if (clock_gettime(CLOCK_MONOTONIC, &ts1))
 		return -1;
@@ -119,29 +118,33 @@ int migrate(uint64_t *ptr, int n1, int n2)
 		if (clock_gettime(CLOCK_MONOTONIC, &ts2))
 			return -1;
 
-		if (ts2.tv_sec - ts1.tv_sec >= RUNTIME)
-			return 0;
+		if (ts2.tv_sec - ts1.tv_sec >= RUNTIME) {
+			/* Reaching both targets verifies a cross-node move. */
+			if (success >= 2)
+				return 0;
+			else
+				return -2;
+		}
 
 		ret = move_pages(0, 1, (void **) &ptr, &n2, &status,
 				MPOL_MF_MOVE_ALL);
-		if (ret) {
-			if (ret > 0) {
-				/* Migration is best effort; try again */
-				if (++failures < MAX_RETRIES)
-					continue;
-				printf("Didn't migrate %d pages\n", ret);
-			}
-			else
-				perror("Couldn't migrate pages");
+		if (ret < 0) {
+			perror("Couldn't migrate pages");
+			return ret;
+		}
+		/* Migration is best effort. Try again */
+		if (ret > 0 || status < 0)
+			continue;
+		if (status != n2) {
+			printf("Page is on node %d instead of target node %d\n",
+			       status, n2);
 			return -2;
 		}
-		failures = 0;
+		success++;
 		tmp = n2;
 		n2 = n1;
 		n1 = tmp;
 	}
-
-	return 0;
 }
 
 void *access_mem(void *ptr)
-- 
2.47.3



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

* Re: [PATCH v3 1/5] selftests/mm: skip COW tmpfile cases when fallocate() is unsupported
  2026-07-27  9:52 ` [PATCH v3 1/5] selftests/mm: skip COW tmpfile cases when fallocate() is unsupported Muhammad Usama Anjum
@ 2026-07-27 16:45   ` Usama Arif
  0 siblings, 0 replies; 9+ messages in thread
From: Usama Arif @ 2026-07-27 16:45 UTC (permalink / raw)
  To: Muhammad Usama Anjum
  Cc: Usama Arif, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Miaohe Lin, Naoya Horiguchi, linux-mm, linux-kselftest,
	linux-kernel, Sarthak Sharma

On Mon, 27 Jul 2026 10:52:17 +0100 Muhammad Usama Anjum <usama.anjum@arm.com> wrote:

> The tmpfile-backed COW cases allocate a one-page file with fallocate()
> before exercising private and shared mappings.  When the filesystem
> backing tmpfile() does not implement fallocate(), setup fails with
> EOPNOTSUPP and no COW behavior is exercised.
> 
> This occurs when the temporary directory resides on a filesystem with
> limited allocation support, such as NFSv3.  Reporting a failure adds
> noise because the test prerequisite is absent rather than the COW
> implementation being broken.
> 
> Report EOPNOTSUPP as a skip.  Continue treating every other fallocate()
> error as a failure so unexpected setup regressions remain visible.
> 
> Tested-by: Sarthak Sharma <sarthak.sharma@arm.com>
> Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
> ---
>  tools/testing/selftests/mm/cow.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
> index 0c627ea89ff7b..c1b8920e29342 100644
> --- a/tools/testing/selftests/mm/cow.c
> +++ b/tools/testing/selftests/mm/cow.c
> @@ -1718,8 +1718,13 @@ static void run_with_tmpfile(non_anon_test_fn fn, const char *desc)
>  
>  	/* File consists of a single page filled with zeroes. */
>  	if (fallocate(fd, 0, 0, pagesize)) {
> -		ksft_perror("fallocate() failed");
> -		log_test_result(KSFT_FAIL);
> +		if (errno == EOPNOTSUPP) {
> +			ksft_print_msg("fallocate() not supported by filesystem\n");
> +			log_test_result(KSFT_SKIP);
> +		} else {
> +			ksft_perror("fallocate() failed");
> +			log_test_result(KSFT_FAIL);
> +		}


Correctly skips only unsupported fallocate() setup

Acked-by: Usama Arif <usama.arif@linux.dev>

>  		goto close;
>  	}
>  
> -- 
> 2.47.3
> 
> 


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

* Re: [PATCH v3 2/5] selftests/mm: skip guard hole-punch test if MADV_REMOVE is unsupported
  2026-07-27  9:52 ` [PATCH v3 2/5] selftests/mm: skip guard hole-punch test if MADV_REMOVE " Muhammad Usama Anjum
@ 2026-07-27 16:52   ` Usama Arif
  0 siblings, 0 replies; 9+ messages in thread
From: Usama Arif @ 2026-07-27 16:52 UTC (permalink / raw)
  To: Muhammad Usama Anjum
  Cc: Usama Arif, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Miaohe Lin, Naoya Horiguchi, linux-mm, linux-kselftest,
	linux-kernel, Sarthak Sharma

On Mon, 27 Jul 2026 10:52:18 +0100 Muhammad Usama Anjum <usama.anjum@arm.com> wrote:

> The hole_punch case verifies that guard regions survive MADV_REMOVE and
> that the backing range is punched out.  MADV_REMOVE delegates the hole
> punch to the backing filesystem, which may reject the operation with
> EOPNOTSUPP.
> 
> That result means the test cannot establish the state whose guard
> semantics it intends to validate.  Treating the missing filesystem
> capability as a guard-region failure creates a false regression.
> 
> Unmap the range and skip only when MADV_REMOVE fails with EOPNOTSUPP.
> Preserve the assertion for all other errors so failures on supported
> configurations remain visible.
> 
> Tested-by: Sarthak Sharma <sarthak.sharma@arm.com>
> Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
> ---
>  tools/testing/selftests/mm/guard-regions.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/testing/selftests/mm/guard-regions.c b/tools/testing/selftests/mm/guard-regions.c
> index b21df3040b1c7..5c8ec3ca75d7d 100644
> --- a/tools/testing/selftests/mm/guard-regions.c
> +++ b/tools/testing/selftests/mm/guard-regions.c
> @@ -1912,7 +1912,7 @@ TEST_F(guard_regions, hole_punch)
>  {
>  	const unsigned long page_size = self->page_size;
>  	char *ptr;
> -	int i;
> +	int i, ret;
>  
>  	if (variant->backing == ANON_BACKED)
>  		SKIP(return, "Truncation test specific to file-backed");
> @@ -1944,8 +1944,12 @@ TEST_F(guard_regions, hole_punch)
>  	}
>  
>  	/* Now hole punch the guarded region. */
> -	ASSERT_EQ(madvise(&ptr[3 * page_size], 4 * page_size,
> -			  MADV_REMOVE), 0);
> +	ret = madvise(&ptr[3 * page_size], 4 * page_size, MADV_REMOVE);
> +	if (ret == -1 && errno == EOPNOTSUPP) {
> +		ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
> +		SKIP(return, "MADV_REMOVE not supported by filesystem");
> +	}
> +	ASSERT_EQ(ret, 0);

Correctly treats MADV_REMOVE EOPNOTSUPP as a missing prerequisite and unmaps before skipping

Acked-by: Usama Arif <usama.arif@linux.dev>

>  
>  	/* Ensure guard regions remain. */
>  	for (i = 0; i < 10; i++) {
> -- 
> 2.47.3
> 
> 


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

* Re: [PATCH v3 3/5] selftests/mm: skip khugepaged swap tests without swap
  2026-07-27  9:52 ` [PATCH v3 3/5] selftests/mm: skip khugepaged swap tests without swap Muhammad Usama Anjum
@ 2026-07-27 17:18   ` Usama Arif
  0 siblings, 0 replies; 9+ messages in thread
From: Usama Arif @ 2026-07-27 17:18 UTC (permalink / raw)
  To: Muhammad Usama Anjum
  Cc: Usama Arif, Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
	Suren Baghdasaryan, Michal Hocko, Shuah Khan, Zi Yan, Baolin Wang,
	Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
	Miaohe Lin, Naoya Horiguchi, linux-mm, linux-kselftest,
	linux-kernel

On Mon, 27 Jul 2026 10:52:19 +0100 Muhammad Usama Anjum <usama.anjum@arm.com> wrote:

> collapse_swapin_single_pte and collapse_max_ptes_swap require
> MADV_PAGEOUT to replace anonymous pages with swap entries. On swapless
> systems there is no backing store with which to create those entries,
> so check_swap() reports missing setup rather than broken khugepaged
> behavior.
> 
> Swapless configurations are common on Android and other constrained
> test devices. Failing these cases obscures actionable results from the
> rest of the khugepaged suite.
> 
> Check /proc/swaps before either swap-dependent case and skip when no
> active swap area exists. With swap present, retain the existing
> MADV_PAGEOUT and swap-entry assertions unchanged.
> 
> Print each existing swapout diagnostic before the prerequisite check
> so skip() completes a KTAP diagnostic line instead of emitting an
> unprefixed message.
> 
> Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
> ---
> Changes since v1:
> - Print swapout diagnostics before reporting no-swap skips.
> ---
>  tools/testing/selftests/mm/khugepaged.c | 38 +++++++++++++++++++++++--
>  1 file changed, 36 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/mm/khugepaged.c b/tools/testing/selftests/mm/khugepaged.c
> index 10e8dedcb087d..54e888eb48bbc 100644
> --- a/tools/testing/selftests/mm/khugepaged.c
> +++ b/tools/testing/selftests/mm/khugepaged.c
> @@ -100,6 +100,28 @@ static void skip(const char *msg)
>  	exit_status = KSFT_SKIP;
>  }
>  
> +static bool is_swap_enabled(void)
> +{
> +	char buf[MAX_LINE_LENGTH];
> +	FILE *file;
> +	bool enabled = false;
> +
> +	file = fopen("/proc/swaps", "r");
> +	if (!file)
> +		return false;
> +
> +	if (!fgets(buf, sizeof(buf), file))
> +		goto out;
> +
> +	/* Check for first active swap entry. */
> +	if (fgets(buf, sizeof(buf), file))
> +		enabled = true;
> +
> +out:
> +	fclose(file);
> +	return enabled;
> +}
> +

Could is_swap_enabled() be moved to vm_util.c. This will definitely be reusable
in other places.

>  static void save_settings(void)
>  {
>  	ksft_print_msg("Save THP and khugepaged settings...");
> @@ -734,10 +756,16 @@ static void collapse_swapin_single_pte(struct collapse_context *c, struct mem_op
>  {
>  	void *p;
>  
> +	ksft_print_msg("Swapout one page...");
> +	if (!is_swap_enabled()) {
> +		skip("No active swap");
> +		ksft_test_result_report(exit_status, "%s\n", __func__);
> +		return;
> +	}
> +
>  	p = ops->setup_area(1);
>  	ops->fault(p, 0, hpage_pmd_size);
>  
> -	ksft_print_msg("Swapout one page...");
>  	if (madvise(p, page_size, MADV_PAGEOUT))
>  		ksft_exit_fail_perror("madvise(MADV_PAGEOUT)");
>  	if (check_swap(p, page_size)) {
> @@ -760,10 +788,16 @@ static void collapse_max_ptes_swap(struct collapse_context *c, struct mem_ops *o
>  	int max_ptes_swap = thp_read_num("khugepaged/max_ptes_swap");
>  	void *p;
>  
> +	ksft_print_msg("Swapout %d of %d pages...", max_ptes_swap + 1, hpage_pmd_nr);
> +	if (!is_swap_enabled()) {
> +		skip("No active swap");
> +		ksft_test_result_report(exit_status, "%s\n", __func__);
> +		return;
> +	}
> +
>  	p = ops->setup_area(1);
>  	ops->fault(p, 0, hpage_pmd_size);
>  
> -	ksft_print_msg("Swapout %d of %d pages...", max_ptes_swap + 1, hpage_pmd_nr);
>  	if (madvise(p, (max_ptes_swap + 1) * page_size, MADV_PAGEOUT))
>  		ksft_exit_fail_perror("madvise(MADV_PAGEOUT)");
>  	if (check_swap(p, (max_ptes_swap + 1) * page_size)) {
> -- 
> 2.47.3
> 
> 


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

end of thread, other threads:[~2026-07-27 17:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27  9:52 [PATCH v3 0/5] selftests/mm: Handle unsupported and transient test conditions Muhammad Usama Anjum
2026-07-27  9:52 ` [PATCH v3 1/5] selftests/mm: skip COW tmpfile cases when fallocate() is unsupported Muhammad Usama Anjum
2026-07-27 16:45   ` Usama Arif
2026-07-27  9:52 ` [PATCH v3 2/5] selftests/mm: skip guard hole-punch test if MADV_REMOVE " Muhammad Usama Anjum
2026-07-27 16:52   ` Usama Arif
2026-07-27  9:52 ` [PATCH v3 3/5] selftests/mm: skip khugepaged swap tests without swap Muhammad Usama Anjum
2026-07-27 17:18   ` Usama Arif
2026-07-27  9:52 ` [PATCH v3 4/5] selftests/mm: skip hard dirty page-cache test on NFS Muhammad Usama Anjum
2026-07-27  9:52 ` [PATCH v3 5/5] selftests/mm: retry migration failures for the full runtime Muhammad Usama Anjum

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