* [PATCH v3 1/9] selftests/mm: default KDIR to build directory
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 2/9] selftests/mm: remove flaky header check Kevin Brodsky
` (8 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
KDIR currently defaults to the running kernel's modules directory
when building the page_frag module. The underlying assumption is
that most users build the kselftests in order to run them against
the system they're built on.
This assumption seems questionable, and there is no guarantee that
the module can actually be built against the running kernel.
Switch the default value of KDIR to the kernel's build directory,
i.e. $(O) if O= or KBUILD_OUTPUT= is used, and the source directory
otherwise. This seems like the least surprising option: the test
module is built against the kernel that has been previously built.
Note: we can't use $(top_srcdir) in mm/Makefile because it is only
defined once lib.mk is included.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/Makefile | 2 +-
tools/testing/selftests/mm/page_frag/Makefile | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index eaf9312097f7..bb93101e339e 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -44,7 +44,7 @@ LDLIBS = -lrt -lpthread -lm
# warnings.
CFLAGS += -U_FORTIFY_SOURCE
-KDIR ?= /lib/modules/$(shell uname -r)/build
+KDIR ?= $(if $(O),$(O),$(realpath ../../../..))
ifneq (,$(wildcard $(KDIR)/Module.symvers))
ifneq (,$(wildcard $(KDIR)/include/linux/page_frag_cache.h))
TEST_GEN_MODS_DIR := page_frag
diff --git a/tools/testing/selftests/mm/page_frag/Makefile b/tools/testing/selftests/mm/page_frag/Makefile
index 8c8bb39ffa28..96e5f646e69b 100644
--- a/tools/testing/selftests/mm/page_frag/Makefile
+++ b/tools/testing/selftests/mm/page_frag/Makefile
@@ -1,5 +1,5 @@
PAGE_FRAG_TEST_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
-KDIR ?= /lib/modules/$(shell uname -r)/build
+KDIR ?= $(if $(O),$(O),$(realpath ../../../../..))
ifeq ($(V),1)
Q =
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* [PATCH v3 2/9] selftests/mm: remove flaky header check
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 1/9] selftests/mm: default KDIR to build directory Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 3/9] selftests/mm: pass down full CC and CFLAGS to check_config.sh Kevin Brodsky
` (7 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan,
Paolo Abeni, Yunsheng Lin
Commit 96ed62ea0298 ("mm: page_frag: fix a compile error when kernel
is not compiled") introduced a check to avoid attempting to build
the page_frag module if <linux/page_frag_cache.h> is missing.
Unfortunately this check only works if KDIR points to
/lib/modules/... or an in-tree kernel build. It always fails if KDIR
points to an out-of-tree build (i.e. when the kernel was built with
O=... make) because only generated headers are present under
$KDIR/include/ in that case.
A recent commit switched KDIR to default to the kernel's build
directory, so that check is no longer justified.
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Yunsheng Lin <linyunsheng@huawei.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/Makefile | 4 ----
1 file changed, 4 deletions(-)
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index bb93101e339e..4e5c8a330a0c 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -46,12 +46,8 @@ CFLAGS += -U_FORTIFY_SOURCE
KDIR ?= $(if $(O),$(O),$(realpath ../../../..))
ifneq (,$(wildcard $(KDIR)/Module.symvers))
-ifneq (,$(wildcard $(KDIR)/include/linux/page_frag_cache.h))
TEST_GEN_MODS_DIR := page_frag
else
-PAGE_FRAG_WARNING = "missing page_frag_cache.h, please use a newer kernel"
-endif
-else
PAGE_FRAG_WARNING = "missing Module.symvers, please have the kernel built first"
endif
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* [PATCH v3 3/9] selftests/mm: pass down full CC and CFLAGS to check_config.sh
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 1/9] selftests/mm: default KDIR to build directory Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 2/9] selftests/mm: remove flaky header check Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 4/9] selftests/mm: fix usage of FORCE_READ() in cow tests Kevin Brodsky
` (6 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan,
Jason Gunthorpe, John Hubbard
check_config.sh checks that liburing is available by running the
compiler provided as its first argument. This makes two assumptions:
1. CC consists of only one word
2. No extra flag is required
Unfortunately, there are many situations where these assumptions
don't hold. For instance:
- When using Clang, CC consists of multiple words
- When cross-compiling, extra flags may be required to allow the
compiler to find headers
Remove these assumptions by passing down CC and CFLAGS as-is from
the Makefile, so that the same command line is used as when actually
building the tests.
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/Makefile | 2 +-
tools/testing/selftests/mm/check_config.sh | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile
index 4e5c8a330a0c..de4afc34e3b1 100644
--- a/tools/testing/selftests/mm/Makefile
+++ b/tools/testing/selftests/mm/Makefile
@@ -230,7 +230,7 @@ $(OUTPUT)/migration: LDLIBS += -lnuma
$(OUTPUT)/rmap: LDLIBS += -lnuma
local_config.mk local_config.h: check_config.sh
- /bin/sh ./check_config.sh $(CC)
+ CC="$(CC)" CFLAGS="$(CFLAGS)" ./check_config.sh
EXTRA_CLEAN += local_config.mk local_config.h
diff --git a/tools/testing/selftests/mm/check_config.sh b/tools/testing/selftests/mm/check_config.sh
index 3954f4746161..b84c82bbf875 100755
--- a/tools/testing/selftests/mm/check_config.sh
+++ b/tools/testing/selftests/mm/check_config.sh
@@ -16,8 +16,7 @@ echo "#include <sys/types.h>" > $tmpfile_c
echo "#include <liburing.h>" >> $tmpfile_c
echo "int func(void) { return 0; }" >> $tmpfile_c
-CC=${1:?"Usage: $0 <compiler> # example compiler: gcc"}
-$CC -c $tmpfile_c -o $tmpfile_o >/dev/null 2>&1
+$CC $CFLAGS -c $tmpfile_c -o $tmpfile_o
if [ -f $tmpfile_o ]; then
echo "#define LOCAL_CONFIG_HAVE_LIBURING 1" > $OUTPUT_H_FILE
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* [PATCH v3 4/9] selftests/mm: fix usage of FORCE_READ() in cow tests
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
` (2 preceding siblings ...)
2026-01-22 17:02 ` [PATCH v3 3/9] selftests/mm: pass down full CC and CFLAGS to check_config.sh Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded Kevin Brodsky
` (5 subsequent siblings)
9 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan,
SeongJae Park, wang lian
Commit 5bbc2b785e63 ("selftests/mm: fix FORCE_READ to read input
value correctly") modified FORCE_READ() to take a value instead of a
pointer. It also changed most of the call sites accordingly, but
missed many of them in cow.c. In those cases, we ended up with the
pointer itself being read, not the memory it points to.
No failure occurred as a result, so it looks like the tests work
just fine without faulting in. However, the huge_zeropage tests
explicitly check that pages are populated, so those became skipped.
Convert all the remaining FORCE_READ() to fault in the mapped page,
as was originally intended. This allows the huge_zeropage tests to
run again (3 tests in total).
Fixes: 5bbc2b785e63 ("selftests/mm: fix FORCE_READ to read input value correctly")
Acked-by: SeongJae Park <sj@kernel.org>
Reviewed-by: wang lian <lianux.mm@gmail.com>
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/cow.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
index accfd198dbda..83b3563be26b 100644
--- a/tools/testing/selftests/mm/cow.c
+++ b/tools/testing/selftests/mm/cow.c
@@ -1612,8 +1612,8 @@ static void run_with_huge_zeropage(non_anon_test_fn fn, const char *desc)
* the first sub-page and test if we get another sub-page populated
* automatically.
*/
- FORCE_READ(mem);
- FORCE_READ(smem);
+ FORCE_READ(*mem);
+ FORCE_READ(*smem);
if (!pagemap_is_populated(pagemap_fd, mem + pagesize) ||
!pagemap_is_populated(pagemap_fd, smem + pagesize)) {
ksft_test_result_skip("Did not get THPs populated\n");
@@ -1663,8 +1663,8 @@ static void run_with_memfd(non_anon_test_fn fn, const char *desc)
}
/* Fault the page in. */
- FORCE_READ(mem);
- FORCE_READ(smem);
+ FORCE_READ(*mem);
+ FORCE_READ(*smem);
fn(mem, smem, pagesize);
munmap:
@@ -1719,8 +1719,8 @@ static void run_with_tmpfile(non_anon_test_fn fn, const char *desc)
}
/* Fault the page in. */
- FORCE_READ(mem);
- FORCE_READ(smem);
+ FORCE_READ(*mem);
+ FORCE_READ(*smem);
fn(mem, smem, pagesize);
munmap:
@@ -1773,8 +1773,8 @@ static void run_with_memfd_hugetlb(non_anon_test_fn fn, const char *desc,
}
/* Fault the page in. */
- FORCE_READ(mem);
- FORCE_READ(smem);
+ FORCE_READ(*mem);
+ FORCE_READ(*smem);
fn(mem, smem, hugetlbsize);
munmap:
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
` (3 preceding siblings ...)
2026-01-22 17:02 ` [PATCH v3 4/9] selftests/mm: fix usage of FORCE_READ() in cow tests Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:36 ` Usama Anjum
2026-01-22 22:18 ` David Hildenbrand (Red Hat)
2026-01-22 17:02 ` [PATCH v3 6/9] selftests/mm: introduce helper to read every page Kevin Brodsky
` (4 subsequent siblings)
9 siblings, 2 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
Many cow tests rely on FORCE_READ() to populate pages. Introduce a
helper to make sure that the pages are actually populated, and fail
otherwise.
Suggested-by: David Hildenbrand (Red Hat) <david@kernel.org>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/cow.c | 43 ++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
index 83b3563be26b..d9c69c04b67d 100644
--- a/tools/testing/selftests/mm/cow.c
+++ b/tools/testing/selftests/mm/cow.c
@@ -75,6 +75,18 @@ static bool range_is_swapped(void *addr, size_t size)
return true;
}
+static bool populate_page_checked(char *addr)
+{
+ bool ret;
+
+ FORCE_READ(*addr);
+ ret = pagemap_is_populated(pagemap_fd, addr);
+ if (!ret)
+ ksft_print_msg("Failed to populate page\n");
+
+ return ret;
+}
+
struct comm_pipes {
int child_ready[2];
int parent_ready[2];
@@ -1549,8 +1561,10 @@ static void run_with_zeropage(non_anon_test_fn fn, const char *desc)
}
/* Read from the page to populate the shared zeropage. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, pagesize);
munmap:
@@ -1612,8 +1626,11 @@ static void run_with_huge_zeropage(non_anon_test_fn fn, const char *desc)
* the first sub-page and test if we get another sub-page populated
* automatically.
*/
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
+
if (!pagemap_is_populated(pagemap_fd, mem + pagesize) ||
!pagemap_is_populated(pagemap_fd, smem + pagesize)) {
ksft_test_result_skip("Did not get THPs populated\n");
@@ -1663,8 +1680,10 @@ static void run_with_memfd(non_anon_test_fn fn, const char *desc)
}
/* Fault the page in. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, pagesize);
munmap:
@@ -1719,8 +1738,10 @@ static void run_with_tmpfile(non_anon_test_fn fn, const char *desc)
}
/* Fault the page in. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, pagesize);
munmap:
@@ -1773,8 +1794,10 @@ static void run_with_memfd_hugetlb(non_anon_test_fn fn, const char *desc,
}
/* Fault the page in. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, hugetlbsize);
munmap:
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded
2026-01-22 17:02 ` [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded Kevin Brodsky
@ 2026-01-22 17:36 ` Usama Anjum
2026-01-23 8:20 ` Kevin Brodsky
2026-01-22 22:18 ` David Hildenbrand (Red Hat)
1 sibling, 1 reply; 20+ messages in thread
From: Usama Anjum @ 2026-01-22 17:36 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm, linux-kselftest
Cc: usama.anjum, linux-kernel, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
On 22/01/2026 5:02 pm, Kevin Brodsky wrote:
> Many cow tests rely on FORCE_READ() to populate pages. Introduce a
> helper to make sure that the pages are actually populated, and fail
> otherwise.
>
> Suggested-by: David Hildenbrand (Red Hat) <david@kernel.org>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> tools/testing/selftests/mm/cow.c | 43 ++++++++++++++++++++++++--------
> 1 file changed, 33 insertions(+), 10 deletions(-)
>
> diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
> index 83b3563be26b..d9c69c04b67d 100644
> --- a/tools/testing/selftests/mm/cow.c
> +++ b/tools/testing/selftests/mm/cow.c
> @@ -75,6 +75,18 @@ static bool range_is_swapped(void *addr, size_t size)
> return true;
> }
>
> +static bool populate_page_checked(char *addr)
> +{
> + bool ret;
> +
> + FORCE_READ(*addr);
> + ret = pagemap_is_populated(pagemap_fd, addr);
Very useful. Maybe extending FORCE_READ can help the entire suite?
> + if (!ret)
> + ksft_print_msg("Failed to populate page\n");
> +
> + return ret;
> +}
> +
> struct comm_pipes {
> int child_ready[2];
> int parent_ready[2];
> @@ -1549,8 +1561,10 @@ static void run_with_zeropage(non_anon_test_fn fn, const char *desc)
> }
>
> /* Read from the page to populate the shared zeropage. */
> - FORCE_READ(*mem);
> - FORCE_READ(*smem);
> + if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
> + log_test_result(KSFT_FAIL);
> + goto munmap;
> + }
>
> fn(mem, smem, pagesize);
> munmap:
> @@ -1612,8 +1626,11 @@ static void run_with_huge_zeropage(non_anon_test_fn fn, const char *desc)
> * the first sub-page and test if we get another sub-page populated
> * automatically.
> */
> - FORCE_READ(*mem);
> - FORCE_READ(*smem);
> + if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
> + log_test_result(KSFT_FAIL);
> + goto munmap;
> + }
> +
> if (!pagemap_is_populated(pagemap_fd, mem + pagesize) ||
> !pagemap_is_populated(pagemap_fd, smem + pagesize)) {
> ksft_test_result_skip("Did not get THPs populated\n");
> @@ -1663,8 +1680,10 @@ static void run_with_memfd(non_anon_test_fn fn, const char *desc)
> }
>
> /* Fault the page in. */
> - FORCE_READ(*mem);
> - FORCE_READ(*smem);
> + if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
> + log_test_result(KSFT_FAIL);
> + goto munmap;
> + }
>
> fn(mem, smem, pagesize);
> munmap:
> @@ -1719,8 +1738,10 @@ static void run_with_tmpfile(non_anon_test_fn fn, const char *desc)
> }
>
> /* Fault the page in. */
> - FORCE_READ(*mem);
> - FORCE_READ(*smem);
> + if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
> + log_test_result(KSFT_FAIL);
> + goto munmap;
> + }
>
> fn(mem, smem, pagesize);
> munmap:
> @@ -1773,8 +1794,10 @@ static void run_with_memfd_hugetlb(non_anon_test_fn fn, const char *desc,
> }
>
> /* Fault the page in. */
> - FORCE_READ(*mem);
> - FORCE_READ(*smem);
> + if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
> + log_test_result(KSFT_FAIL);
> + goto munmap;
> + }
>
> fn(mem, smem, hugetlbsize);
> munmap:
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded
2026-01-22 17:36 ` Usama Anjum
@ 2026-01-23 8:20 ` Kevin Brodsky
0 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-23 8:20 UTC (permalink / raw)
To: Usama Anjum, linux-mm, linux-kselftest
Cc: linux-kernel, Andrew Morton, David Hildenbrand, Dev Jain,
Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
On 22/01/2026 18:36, Usama Anjum wrote:
>> +static bool populate_page_checked(char *addr)
>> +{
>> + bool ret;
>> +
>> + FORCE_READ(*addr);
>> + ret = pagemap_is_populated(pagemap_fd, addr);
> Very useful. Maybe extending FORCE_READ can help the entire suite?
I considered it but one needs to have a pagemap fd around, so we'd have
to open it for every test that uses the helper. Maybe such check is not
so essential either (see David's reply).
- Kevin
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded
2026-01-22 17:02 ` [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded Kevin Brodsky
2026-01-22 17:36 ` Usama Anjum
@ 2026-01-22 22:18 ` David Hildenbrand (Red Hat)
2026-01-23 8:17 ` Kevin Brodsky
1 sibling, 1 reply; 20+ messages in thread
From: David Hildenbrand (Red Hat) @ 2026-01-22 22:18 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm, linux-kselftest
Cc: linux-kernel, Andrew Morton, Dev Jain, Lorenzo Stoakes,
Mark Brown, Ryan Roberts, Shuah Khan
On 1/22/26 18:02, Kevin Brodsky wrote:
> Many cow tests rely on FORCE_READ() to populate pages. Introduce a
> helper to make sure that the pages are actually populated, and fail
> otherwise.
>
> Suggested-by: David Hildenbrand (Red Hat) <david@kernel.org>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> tools/testing/selftests/mm/cow.c | 43 ++++++++++++++++++++++++--------
> 1 file changed, 33 insertions(+), 10 deletions(-)
>
> diff --git a/tools/testing/selftests/mm/cow.c b/tools/testing/selftests/mm/cow.c
> index 83b3563be26b..d9c69c04b67d 100644
> --- a/tools/testing/selftests/mm/cow.c
> +++ b/tools/testing/selftests/mm/cow.c
> @@ -75,6 +75,18 @@ static bool range_is_swapped(void *addr, size_t size)
> return true;
> }
>
> +static bool populate_page_checked(char *addr)
> +{
> + bool ret;
> +
> + FORCE_READ(*addr);
> + ret = pagemap_is_populated(pagemap_fd, addr);
> + if (!ret)
> + ksft_print_msg("Failed to populate page\n");
> +
> + return ret;
> +}
LGTM.
On second thought, this primarily catches if someone breaks FORCE_READ()
... which hopefully doesn't happen that often? ;)
Because if the read succeeded, surely there must be something in the
page tables.
--
Cheers
David
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded
2026-01-22 22:18 ` David Hildenbrand (Red Hat)
@ 2026-01-23 8:17 ` Kevin Brodsky
0 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-23 8:17 UTC (permalink / raw)
To: David Hildenbrand (Red Hat), linux-mm, linux-kselftest
Cc: linux-kernel, Andrew Morton, Dev Jain, Lorenzo Stoakes,
Mark Brown, Ryan Roberts, Shuah Khan
On 22/01/2026 23:18, David Hildenbrand (Red Hat) wrote:
> On 1/22/26 18:02, Kevin Brodsky wrote:
>> Many cow tests rely on FORCE_READ() to populate pages. Introduce a
>> helper to make sure that the pages are actually populated, and fail
>> otherwise.
>>
>> Suggested-by: David Hildenbrand (Red Hat) <david@kernel.org>
>> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
>> ---
>> tools/testing/selftests/mm/cow.c | 43 ++++++++++++++++++++++++--------
>> 1 file changed, 33 insertions(+), 10 deletions(-)
>>
>> diff --git a/tools/testing/selftests/mm/cow.c
>> b/tools/testing/selftests/mm/cow.c
>> index 83b3563be26b..d9c69c04b67d 100644
>> --- a/tools/testing/selftests/mm/cow.c
>> +++ b/tools/testing/selftests/mm/cow.c
>> @@ -75,6 +75,18 @@ static bool range_is_swapped(void *addr, size_t size)
>> return true;
>> }
>> +static bool populate_page_checked(char *addr)
>> +{
>> + bool ret;
>> +
>> + FORCE_READ(*addr);
>> + ret = pagemap_is_populated(pagemap_fd, addr);
>> + if (!ret)
>> + ksft_print_msg("Failed to populate page\n");
>> +
>> + return ret;
>> +}
>
> LGTM.
>
> On second thought, this primarily catches if someone breaks
> FORCE_READ() ... which hopefully doesn't happen that often? ;)
>
> Because if the read succeeded, surely there must be something in the
> page tables.
Indeed, one would hope so! The check doesn't hurt either though
(especially since we already have the pagemap fd around).
- Kevin
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 6/9] selftests/mm: introduce helper to read every page
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
` (4 preceding siblings ...)
2026-01-22 17:02 ` [PATCH v3 5/9] selftests/mm: check that FORCE_READ() succeeded Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:39 ` Muhammad Usama Anjum
2026-01-22 22:20 ` David Hildenbrand (Red Hat)
2026-01-22 17:02 ` [PATCH v3 7/9] selftests/mm: fix faulting-in code in pagemap_ioctl test Kevin Brodsky
` (3 subsequent siblings)
9 siblings, 2 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
FORCE_READ(*addr) ensures that the compiler will emit a load from
addr. Several tests need to trigger such a load for a range of
pages, ensuring that every page is faulted in, if it wasn't already.
Introduce a new helper force_read_pages() that does exactly that and
replace existing loops with a call to it.
The step size (regular/huge page size) is preserved for all loops,
except in split_huge_page_test. Reading every byte is unnecessary;
we now read every huge page, matching the following call to
check_huge_file().
Reviewed-by: Dev Jain <dev.jain@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/hugetlb-madvise.c | 9 +--------
tools/testing/selftests/mm/pfnmap.c | 9 +++------
tools/testing/selftests/mm/split_huge_page_test.c | 6 +-----
tools/testing/selftests/mm/vm_util.h | 7 +++++++
4 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
index 05d9d2805ae4..5b12041fa310 100644
--- a/tools/testing/selftests/mm/hugetlb-madvise.c
+++ b/tools/testing/selftests/mm/hugetlb-madvise.c
@@ -47,14 +47,7 @@ void write_fault_pages(void *addr, unsigned long nr_pages)
void read_fault_pages(void *addr, unsigned long nr_pages)
{
- unsigned long i;
-
- for (i = 0; i < nr_pages; i++) {
- unsigned long *addr2 =
- ((unsigned long *)(addr + (i * huge_page_size)));
- /* Prevent the compiler from optimizing out the entire loop: */
- FORCE_READ(*addr2);
- }
+ force_read_pages(addr, nr_pages, huge_page_size);
}
int main(int argc, char **argv)
diff --git a/tools/testing/selftests/mm/pfnmap.c b/tools/testing/selftests/mm/pfnmap.c
index f546dfb10cae..45b5f1cf6019 100644
--- a/tools/testing/selftests/mm/pfnmap.c
+++ b/tools/testing/selftests/mm/pfnmap.c
@@ -35,18 +35,15 @@ static void signal_handler(int sig)
static int test_read_access(char *addr, size_t size, size_t pagesize)
{
- size_t offs;
int ret;
if (signal(SIGSEGV, signal_handler) == SIG_ERR)
return -EINVAL;
ret = sigsetjmp(sigjmp_buf_env, 1);
- if (!ret) {
- for (offs = 0; offs < size; offs += pagesize)
- /* Force a read that the compiler cannot optimize out. */
- *((volatile char *)(addr + offs));
- }
+ if (!ret)
+ force_read_pages(addr, size/pagesize, pagesize);
+
if (signal(SIGSEGV, SIG_DFL) == SIG_ERR)
return -EINVAL;
diff --git a/tools/testing/selftests/mm/split_huge_page_test.c b/tools/testing/selftests/mm/split_huge_page_test.c
index 40799f3f0213..e0167111bdd1 100644
--- a/tools/testing/selftests/mm/split_huge_page_test.c
+++ b/tools/testing/selftests/mm/split_huge_page_test.c
@@ -652,11 +652,7 @@ static int create_pagecache_thp_and_fd(const char *testfile, size_t fd_size,
}
madvise(*addr, fd_size, MADV_HUGEPAGE);
- for (size_t i = 0; i < fd_size; i++) {
- char *addr2 = *addr + i;
-
- FORCE_READ(*addr2);
- }
+ force_read_pages(*addr, fd_size / pmd_pagesize, pmd_pagesize);
if (!check_huge_file(*addr, fd_size / pmd_pagesize, pmd_pagesize)) {
ksft_print_msg("No large pagecache folio generated, please provide a filesystem supporting large folio\n");
diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h
index 6ad32b1830f1..522f7f9050f5 100644
--- a/tools/testing/selftests/mm/vm_util.h
+++ b/tools/testing/selftests/mm/vm_util.h
@@ -54,6 +54,13 @@ static inline unsigned int pshift(void)
return __page_shift;
}
+static inline void force_read_pages(char *addr, unsigned int nr_pages,
+ size_t pagesize)
+{
+ for (unsigned int i = 0; i < nr_pages; i++)
+ FORCE_READ(addr[i * pagesize]);
+}
+
bool detect_huge_zeropage(void);
/*
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 6/9] selftests/mm: introduce helper to read every page
2026-01-22 17:02 ` [PATCH v3 6/9] selftests/mm: introduce helper to read every page Kevin Brodsky
@ 2026-01-22 17:39 ` Muhammad Usama Anjum
2026-01-22 22:20 ` David Hildenbrand (Red Hat)
1 sibling, 0 replies; 20+ messages in thread
From: Muhammad Usama Anjum @ 2026-01-22 17:39 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm, linux-kselftest
Cc: linux-kernel, Andrew Morton, David Hildenbrand, Dev Jain,
Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
On 22/01/2026 5:02 pm, Kevin Brodsky wrote:
> FORCE_READ(*addr) ensures that the compiler will emit a load from
> addr. Several tests need to trigger such a load for a range of
> pages, ensuring that every page is faulted in, if it wasn't already.
>
> Introduce a new helper force_read_pages() that does exactly that and
> replace existing loops with a call to it.
>
> The step size (regular/huge page size) is preserved for all loops,
> except in split_huge_page_test. Reading every byte is unnecessary;
> we now read every huge page, matching the following call to
> check_huge_file().
>
> Reviewed-by: Dev Jain <dev.jain@arm.com>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> tools/testing/selftests/mm/hugetlb-madvise.c | 9 +--------
> tools/testing/selftests/mm/pfnmap.c | 9 +++------
> tools/testing/selftests/mm/split_huge_page_test.c | 6 +-----
> tools/testing/selftests/mm/vm_util.h | 7 +++++++
> 4 files changed, 12 insertions(+), 19 deletions(-)
>
> diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
> index 05d9d2805ae4..5b12041fa310 100644
> --- a/tools/testing/selftests/mm/hugetlb-madvise.c
> +++ b/tools/testing/selftests/mm/hugetlb-madvise.c
> @@ -47,14 +47,7 @@ void write_fault_pages(void *addr, unsigned long nr_pages)
>
> void read_fault_pages(void *addr, unsigned long nr_pages)
> {
> - unsigned long i;
> -
> - for (i = 0; i < nr_pages; i++) {
> - unsigned long *addr2 =
> - ((unsigned long *)(addr + (i * huge_page_size)));
> - /* Prevent the compiler from optimizing out the entire loop: */
> - FORCE_READ(*addr2);
> - }
> + force_read_pages(addr, nr_pages, huge_page_size);
> }
>
> int main(int argc, char **argv)
> diff --git a/tools/testing/selftests/mm/pfnmap.c b/tools/testing/selftests/mm/pfnmap.c
> index f546dfb10cae..45b5f1cf6019 100644
> --- a/tools/testing/selftests/mm/pfnmap.c
> +++ b/tools/testing/selftests/mm/pfnmap.c
> @@ -35,18 +35,15 @@ static void signal_handler(int sig)
>
> static int test_read_access(char *addr, size_t size, size_t pagesize)
> {
> - size_t offs;
> int ret;
>
> if (signal(SIGSEGV, signal_handler) == SIG_ERR)
> return -EINVAL;
>
> ret = sigsetjmp(sigjmp_buf_env, 1);
> - if (!ret) {
> - for (offs = 0; offs < size; offs += pagesize)
> - /* Force a read that the compiler cannot optimize out. */
> - *((volatile char *)(addr + offs));
> - }
> + if (!ret)
> + force_read_pages(addr, size/pagesize, pagesize);
> +
> if (signal(SIGSEGV, SIG_DFL) == SIG_ERR)
> return -EINVAL;
>
> diff --git a/tools/testing/selftests/mm/split_huge_page_test.c b/tools/testing/selftests/mm/split_huge_page_test.c
> index 40799f3f0213..e0167111bdd1 100644
> --- a/tools/testing/selftests/mm/split_huge_page_test.c
> +++ b/tools/testing/selftests/mm/split_huge_page_test.c
> @@ -652,11 +652,7 @@ static int create_pagecache_thp_and_fd(const char *testfile, size_t fd_size,
> }
> madvise(*addr, fd_size, MADV_HUGEPAGE);
>
> - for (size_t i = 0; i < fd_size; i++) {
> - char *addr2 = *addr + i;
> -
> - FORCE_READ(*addr2);
> - }
> + force_read_pages(*addr, fd_size / pmd_pagesize, pmd_pagesize);
>
> if (!check_huge_file(*addr, fd_size / pmd_pagesize, pmd_pagesize)) {
> ksft_print_msg("No large pagecache folio generated, please provide a filesystem supporting large folio\n");
> diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h
> index 6ad32b1830f1..522f7f9050f5 100644
> --- a/tools/testing/selftests/mm/vm_util.h
> +++ b/tools/testing/selftests/mm/vm_util.h
> @@ -54,6 +54,13 @@ static inline unsigned int pshift(void)
> return __page_shift;
> }
>
> +static inline void force_read_pages(char *addr, unsigned int nr_pages,
> + size_t pagesize)
> +{
> + for (unsigned int i = 0; i < nr_pages; i++)
> + FORCE_READ(addr[i * pagesize]);
> +}
Reviewed-by: Muhammad Usama Anjum <usama.anjum@arm.com>
> +
> bool detect_huge_zeropage(void);
>
> /*
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 6/9] selftests/mm: introduce helper to read every page
2026-01-22 17:02 ` [PATCH v3 6/9] selftests/mm: introduce helper to read every page Kevin Brodsky
2026-01-22 17:39 ` Muhammad Usama Anjum
@ 2026-01-22 22:20 ` David Hildenbrand (Red Hat)
2026-01-23 8:25 ` Kevin Brodsky
1 sibling, 1 reply; 20+ messages in thread
From: David Hildenbrand (Red Hat) @ 2026-01-22 22:20 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm, linux-kselftest
Cc: linux-kernel, Andrew Morton, Dev Jain, Lorenzo Stoakes,
Mark Brown, Ryan Roberts, Shuah Khan
On 1/22/26 18:02, Kevin Brodsky wrote:
> FORCE_READ(*addr) ensures that the compiler will emit a load from
> addr. Several tests need to trigger such a load for a range of
> pages, ensuring that every page is faulted in, if it wasn't already.
>
> Introduce a new helper force_read_pages() that does exactly that and
> replace existing loops with a call to it.
>
> The step size (regular/huge page size) is preserved for all loops,
> except in split_huge_page_test. Reading every byte is unnecessary;
> we now read every huge page, matching the following call to
> check_huge_file().
>
> Reviewed-by: Dev Jain <dev.jain@arm.com>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
> tools/testing/selftests/mm/hugetlb-madvise.c | 9 +--------
> tools/testing/selftests/mm/pfnmap.c | 9 +++------
> tools/testing/selftests/mm/split_huge_page_test.c | 6 +-----
> tools/testing/selftests/mm/vm_util.h | 7 +++++++
> 4 files changed, 12 insertions(+), 19 deletions(-)
>
> diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c b/tools/testing/selftests/mm/hugetlb-madvise.c
> index 05d9d2805ae4..5b12041fa310 100644
> --- a/tools/testing/selftests/mm/hugetlb-madvise.c
> +++ b/tools/testing/selftests/mm/hugetlb-madvise.c
> @@ -47,14 +47,7 @@ void write_fault_pages(void *addr, unsigned long nr_pages)
>
> void read_fault_pages(void *addr, unsigned long nr_pages)
> {
> - unsigned long i;
> -
> - for (i = 0; i < nr_pages; i++) {
> - unsigned long *addr2 =
> - ((unsigned long *)(addr + (i * huge_page_size)));
> - /* Prevent the compiler from optimizing out the entire loop: */
> - FORCE_READ(*addr2);
> - }
> + force_read_pages(addr, nr_pages, huge_page_size);
> }
Likely we could get rid of read_fault_pages() completely and simply let
the callers call force_read_pages() now?
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
--
Cheers
David
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 6/9] selftests/mm: introduce helper to read every page
2026-01-22 22:20 ` David Hildenbrand (Red Hat)
@ 2026-01-23 8:25 ` Kevin Brodsky
0 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-23 8:25 UTC (permalink / raw)
To: David Hildenbrand (Red Hat), linux-mm, linux-kselftest
Cc: linux-kernel, Andrew Morton, Dev Jain, Lorenzo Stoakes,
Mark Brown, Ryan Roberts, Shuah Khan
On 22/01/2026 23:20, David Hildenbrand (Red Hat) wrote:
>> diff --git a/tools/testing/selftests/mm/hugetlb-madvise.c
>> b/tools/testing/selftests/mm/hugetlb-madvise.c
>> index 05d9d2805ae4..5b12041fa310 100644
>> --- a/tools/testing/selftests/mm/hugetlb-madvise.c
>> +++ b/tools/testing/selftests/mm/hugetlb-madvise.c
>> @@ -47,14 +47,7 @@ void write_fault_pages(void *addr, unsigned long
>> nr_pages)
>> void read_fault_pages(void *addr, unsigned long nr_pages)
>> {
>> - unsigned long i;
>> -
>> - for (i = 0; i < nr_pages; i++) {
>> - unsigned long *addr2 =
>> - ((unsigned long *)(addr + (i * huge_page_size)));
>> - /* Prevent the compiler from optimizing out the entire loop: */
>> - FORCE_READ(*addr2);
>> - }
>> + force_read_pages(addr, nr_pages, huge_page_size);
>> }
>
> Likely we could get rid of read_fault_pages() completely and simply
> let the callers call force_read_pages() now?
I considered it but since the test also has write_fault_pages() with the
same arguments, I thought it was better to keep it for symmetry (neither
takes the page size since huge_page_size is a global).
- Kevin
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 7/9] selftests/mm: fix faulting-in code in pagemap_ioctl test
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
` (5 preceding siblings ...)
2026-01-22 17:02 ` [PATCH v3 6/9] selftests/mm: introduce helper to read every page Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:43 ` Muhammad Usama Anjum
2026-01-22 17:02 ` [PATCH v3 8/9] selftests/mm: fix exit code in pagemap_ioctl Kevin Brodsky
` (2 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan,
Usama Anjum
One of the pagemap_ioctl tests attempts to fault in pages by
memcpy()'ing them to an unused buffer. This probably worked
originally, but since commit 46036188ea1f ("selftests/mm: build with
-O2") the compiler is free to optimise away that unused buffer and
the memcpy() with it. As a result there might not be any resident
page in the mapping and the test may fail.
We don't need to copy all that memory anyway. Just fault in every
page.
While at it also make sure to compute the number of pages once using
simple integer arithmetic instead of ceilf() and implicit
conversions.
Fixes: 46036188ea1f ("selftests/mm: build with -O2")
Cc: Usama Anjum <Usama.Anjum@arm.com>
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/pagemap_ioctl.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/mm/pagemap_ioctl.c b/tools/testing/selftests/mm/pagemap_ioctl.c
index 2cb5441f29c7..1896c7d4f72e 100644
--- a/tools/testing/selftests/mm/pagemap_ioctl.c
+++ b/tools/testing/selftests/mm/pagemap_ioctl.c
@@ -1052,11 +1052,10 @@ static void test_simple(void)
int sanity_tests(void)
{
unsigned long long mem_size, vec_size;
- long ret, fd, i, buf_size;
+ long ret, fd, i, buf_size, nr_pages;
struct page_region *vec;
char *mem, *fmem;
struct stat sbuf;
- char *tmp_buf;
/* 1. wrong operation */
mem_size = 10 * page_size;
@@ -1167,14 +1166,14 @@ int sanity_tests(void)
if (fmem == MAP_FAILED)
ksft_exit_fail_msg("error nomem %d %s\n", errno, strerror(errno));
- tmp_buf = malloc(sbuf.st_size);
- memcpy(tmp_buf, fmem, sbuf.st_size);
+ nr_pages = (sbuf.st_size + page_size - 1) / page_size;
+ force_read_pages(fmem, nr_pages, page_size);
ret = pagemap_ioctl(fmem, sbuf.st_size, vec, vec_size, 0, 0,
0, PAGEMAP_NON_WRITTEN_BITS, 0, PAGEMAP_NON_WRITTEN_BITS);
ksft_test_result(ret >= 0 && vec[0].start == (uintptr_t)fmem &&
- LEN(vec[0]) == ceilf((float)sbuf.st_size/page_size) &&
+ LEN(vec[0]) == nr_pages &&
(vec[0].categories & PAGE_IS_FILE),
"%s Memory mapped file\n", __func__);
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 7/9] selftests/mm: fix faulting-in code in pagemap_ioctl test
2026-01-22 17:02 ` [PATCH v3 7/9] selftests/mm: fix faulting-in code in pagemap_ioctl test Kevin Brodsky
@ 2026-01-22 17:43 ` Muhammad Usama Anjum
0 siblings, 0 replies; 20+ messages in thread
From: Muhammad Usama Anjum @ 2026-01-22 17:43 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm, linux-kselftest
Cc: usama.anjum, linux-kernel, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
On 22/01/2026 5:02 pm, Kevin Brodsky wrote:
> One of the pagemap_ioctl tests attempts to fault in pages by
> memcpy()'ing them to an unused buffer. This probably worked
> originally, but since commit 46036188ea1f ("selftests/mm: build with
> -O2") the compiler is free to optimise away that unused buffer and
> the memcpy() with it. As a result there might not be any resident
> page in the mapping and the test may fail.
>
> We don't need to copy all that memory anyway. Just fault in every
> page.
>
> While at it also make sure to compute the number of pages once using
> simple integer arithmetic instead of ceilf() and implicit
> conversions.
>
> Fixes: 46036188ea1f ("selftests/mm: build with -O2")
> Cc: Usama Anjum <Usama.Anjum@arm.com>
> Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
> Reviewed-by: Dev Jain <dev.jain@arm.com>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
Reviewed-by: Muhammad Usama Anjum <usama.anjum@arm.com>
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3 8/9] selftests/mm: fix exit code in pagemap_ioctl
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
` (6 preceding siblings ...)
2026-01-22 17:02 ` [PATCH v3 7/9] selftests/mm: fix faulting-in code in pagemap_ioctl test Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 17:02 ` [PATCH v3 9/9] selftests/mm: report SKIP in pfnmap if a check fails Kevin Brodsky
2026-01-22 18:25 ` [PATCH v3 0/9] Various mm kselftests improvements/fixes Andrew Morton
9 siblings, 0 replies; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan,
Usama Anjum, SeongJae Park, wang lian
Make sure pagemap_ioctl exits with an appropriate value:
* If the tests are run, call ksft_finished() to report the right
status instead of reporting PASS unconditionally.
* Report SKIP if userfaultfd isn't available (in line with other
tests)
* Report FAIL if we failed to open /proc/self/pagemap, as this file
has been added a long time ago and doesn't depend on any CONFIG
option (returning -EINVAL from main() is meaningless)
Cc: Usama Anjum <Usama.Anjum@arm.com>
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
Acked-by: SeongJae Park <sj@kernel.org>
Reviewed-by: wang lian <lianux.mm@gmail.com>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/pagemap_ioctl.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/mm/pagemap_ioctl.c b/tools/testing/selftests/mm/pagemap_ioctl.c
index 1896c7d4f72e..2ca8a7e3c27e 100644
--- a/tools/testing/selftests/mm/pagemap_ioctl.c
+++ b/tools/testing/selftests/mm/pagemap_ioctl.c
@@ -1552,7 +1552,7 @@ int main(int __attribute__((unused)) argc, char *argv[])
ksft_print_header();
if (init_uffd())
- ksft_exit_pass();
+ ksft_exit_skip("Failed to initialize userfaultfd\n");
ksft_set_plan(117);
@@ -1561,7 +1561,7 @@ int main(int __attribute__((unused)) argc, char *argv[])
pagemap_fd = open(PAGEMAP, O_RDONLY);
if (pagemap_fd < 0)
- return -EINVAL;
+ ksft_exit_fail_msg("Failed to open " PAGEMAP "\n");
/* 1. Sanity testing */
sanity_tests_sd();
@@ -1733,5 +1733,5 @@ int main(int __attribute__((unused)) argc, char *argv[])
zeropfn_tests();
close(pagemap_fd);
- ksft_exit_pass();
+ ksft_finished();
}
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* [PATCH v3 9/9] selftests/mm: report SKIP in pfnmap if a check fails
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
` (7 preceding siblings ...)
2026-01-22 17:02 ` [PATCH v3 8/9] selftests/mm: fix exit code in pagemap_ioctl Kevin Brodsky
@ 2026-01-22 17:02 ` Kevin Brodsky
2026-01-22 22:23 ` David Hildenbrand (Red Hat)
2026-01-22 18:25 ` [PATCH v3 0/9] Various mm kselftests improvements/fixes Andrew Morton
9 siblings, 1 reply; 20+ messages in thread
From: Kevin Brodsky @ 2026-01-22 17:02 UTC (permalink / raw)
To: linux-mm, linux-kselftest
Cc: linux-kernel, Kevin Brodsky, Andrew Morton, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
pfnmap currently checks the target file in FIXTURE_SETUP(pfnmap),
meaning once for every test, and skips the test if any check fails.
The target file is the same for every test so this is a little
overkill. More importantly, this approach means that the whole suite
will report PASS even if all the tests are skipped because kernel
configuration (e.g. CONFIG_STRICT_DEVMEM=y) prevented /dev/mem from
being mapped, for instance.
Let's ensure that KSFT_SKIP is returned as exit code if any check
fails by performing the checks in pfnmap_init(), run once. That
function also takes care of finding the offset of the pages to be
mapped and saves it in a global. The file is now opened only once
and the fd saved in a global, but it is still mapped/unmapped for
every test, as some of them modify the mapping.
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
tools/testing/selftests/mm/pfnmap.c | 84 ++++++++++++++++++-----------
1 file changed, 53 insertions(+), 31 deletions(-)
diff --git a/tools/testing/selftests/mm/pfnmap.c b/tools/testing/selftests/mm/pfnmap.c
index 45b5f1cf6019..4f550822385a 100644
--- a/tools/testing/selftests/mm/pfnmap.c
+++ b/tools/testing/selftests/mm/pfnmap.c
@@ -25,8 +25,12 @@
#include "kselftest_harness.h"
#include "vm_util.h"
+#define DEV_MEM_NPAGES 2
+
static sigjmp_buf sigjmp_buf_env;
static char *file = "/dev/mem";
+static off_t file_offset;
+static int fd;
static void signal_handler(int sig)
{
@@ -88,7 +92,7 @@ static int find_ram_target(off_t *offset,
break;
/* We need two pages. */
- if (end > start + 2 * pagesize) {
+ if (end > start + DEV_MEM_NPAGES * pagesize) {
fclose(file);
*offset = start;
return 0;
@@ -97,11 +101,48 @@ static int find_ram_target(off_t *offset,
return -ENOENT;
}
+static void pfnmap_init(void)
+{
+ size_t pagesize = getpagesize();
+ size_t size = DEV_MEM_NPAGES * pagesize;
+ void *addr;
+
+ if (strncmp(file, "/dev/mem", strlen("/dev/mem")) == 0) {
+ int err = find_ram_target(&file_offset, pagesize);
+
+ if (err)
+ ksft_exit_skip("Cannot find ram target in '/proc/iomem': %s\n",
+ strerror(-err));
+ } else {
+ file_offset = 0;
+ }
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0)
+ ksft_exit_skip("Cannot open '%s': %s\n", file, strerror(errno));
+
+ /*
+ * Make sure we can map the file, and perform some basic checks; skip
+ * the whole suite if anything goes wrong.
+ * A fresh mapping is then created for every test case by
+ * FIXTURE_SETUP(pfnmap).
+ */
+ addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, file_offset);
+ if (addr == MAP_FAILED)
+ ksft_exit_skip("Cannot mmap '%s': %s\n", file, strerror(errno));
+
+ if (!check_vmflag_pfnmap(addr))
+ ksft_exit_skip("Invalid file: '%s'. Not pfnmap'ed\n", file);
+
+ if (test_read_access(addr, size, pagesize))
+ ksft_exit_skip("Cannot read-access mmap'ed '%s'\n", file);
+
+ munmap(addr, size);
+}
+
FIXTURE(pfnmap)
{
- off_t offset;
size_t pagesize;
- int dev_mem_fd;
char *addr1;
size_t size1;
char *addr2;
@@ -112,31 +153,10 @@ FIXTURE_SETUP(pfnmap)
{
self->pagesize = getpagesize();
- if (strncmp(file, "/dev/mem", strlen("/dev/mem")) == 0) {
- /* We'll require two physical pages throughout our tests ... */
- if (find_ram_target(&self->offset, self->pagesize))
- SKIP(return,
- "Cannot find ram target in '/proc/iomem'\n");
- } else {
- self->offset = 0;
- }
-
- self->dev_mem_fd = open(file, O_RDONLY);
- if (self->dev_mem_fd < 0)
- SKIP(return, "Cannot open '%s'\n", file);
-
- self->size1 = self->pagesize * 2;
+ self->size1 = DEV_MEM_NPAGES * self->pagesize;
self->addr1 = mmap(NULL, self->size1, PROT_READ, MAP_SHARED,
- self->dev_mem_fd, self->offset);
- if (self->addr1 == MAP_FAILED)
- SKIP(return, "Cannot mmap '%s'\n", file);
-
- if (!check_vmflag_pfnmap(self->addr1))
- SKIP(return, "Invalid file: '%s'. Not pfnmap'ed\n", file);
-
- /* ... and want to be able to read from them. */
- if (test_read_access(self->addr1, self->size1, self->pagesize))
- SKIP(return, "Cannot read-access mmap'ed '%s'\n", file);
+ fd, file_offset);
+ ASSERT_NE(self->addr1, MAP_FAILED);
self->size2 = 0;
self->addr2 = MAP_FAILED;
@@ -148,8 +168,6 @@ FIXTURE_TEARDOWN(pfnmap)
munmap(self->addr2, self->size2);
if (self->addr1 != MAP_FAILED)
munmap(self->addr1, self->size1);
- if (self->dev_mem_fd >= 0)
- close(self->dev_mem_fd);
}
TEST_F(pfnmap, madvise_disallowed)
@@ -189,7 +207,7 @@ TEST_F(pfnmap, munmap_split)
*/
self->size2 = self->pagesize;
self->addr2 = mmap(NULL, self->pagesize, PROT_READ, MAP_SHARED,
- self->dev_mem_fd, self->offset);
+ fd, file_offset);
ASSERT_NE(self->addr2, MAP_FAILED);
}
@@ -259,8 +277,12 @@ int main(int argc, char **argv)
if (strcmp(argv[i], "--") == 0) {
if (i + 1 < argc && strlen(argv[i + 1]) > 0)
file = argv[i + 1];
- return test_harness_run(i, argv);
+ argc = i;
+ break;
}
}
+
+ pfnmap_init();
+
return test_harness_run(argc, argv);
}
--
2.51.2
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: [PATCH v3 9/9] selftests/mm: report SKIP in pfnmap if a check fails
2026-01-22 17:02 ` [PATCH v3 9/9] selftests/mm: report SKIP in pfnmap if a check fails Kevin Brodsky
@ 2026-01-22 22:23 ` David Hildenbrand (Red Hat)
0 siblings, 0 replies; 20+ messages in thread
From: David Hildenbrand (Red Hat) @ 2026-01-22 22:23 UTC (permalink / raw)
To: Kevin Brodsky, linux-mm, linux-kselftest
Cc: linux-kernel, Andrew Morton, Dev Jain, Lorenzo Stoakes,
Mark Brown, Ryan Roberts, Shuah Khan
On 1/22/26 18:02, Kevin Brodsky wrote:
> pfnmap currently checks the target file in FIXTURE_SETUP(pfnmap),
> meaning once for every test, and skips the test if any check fails.
>
> The target file is the same for every test so this is a little
> overkill. More importantly, this approach means that the whole suite
> will report PASS even if all the tests are skipped because kernel
> configuration (e.g. CONFIG_STRICT_DEVMEM=y) prevented /dev/mem from
> being mapped, for instance.
>
> Let's ensure that KSFT_SKIP is returned as exit code if any check
> fails by performing the checks in pfnmap_init(), run once. That
> function also takes care of finding the offset of the pages to be
> mapped and saves it in a global. The file is now opened only once
> and the fd saved in a global, but it is still mapped/unmapped for
> every test, as some of them modify the mapping.
>
> Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
> ---
Acked-by: David Hildenbrand (Red Hat) <david@kernel.org>
--
Cheers
David
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3 0/9] Various mm kselftests improvements/fixes
2026-01-22 17:02 [PATCH v3 0/9] Various mm kselftests improvements/fixes Kevin Brodsky
` (8 preceding siblings ...)
2026-01-22 17:02 ` [PATCH v3 9/9] selftests/mm: report SKIP in pfnmap if a check fails Kevin Brodsky
@ 2026-01-22 18:25 ` Andrew Morton
9 siblings, 0 replies; 20+ messages in thread
From: Andrew Morton @ 2026-01-22 18:25 UTC (permalink / raw)
To: Kevin Brodsky
Cc: linux-mm, linux-kselftest, linux-kernel, David Hildenbrand,
Dev Jain, Lorenzo Stoakes, Mark Brown, Ryan Roberts, Shuah Khan
On Thu, 22 Jan 2026 17:02:15 +0000 Kevin Brodsky <kevin.brodsky@arm.com> wrote:
> Various improvements/fixes for the mm kselftests:
>
> - Patch 1-3 extend support for more build configurations: out-of-tree
> $KDIR, cross-compilation, etc.
>
> - Patch 4-7 fix issues related to faulting in pages, introducing a new
> helper for that purpose.
>
> - Patch 8 fixes the value returned by pagemap_ioctl (PASS was always
> returned, which explains why the issue fixed in patch 6 went
> unnoticed).
>
> - Patch 9 improves the exit code of pfnmap.
>
> Net results:
> - 1 test no longer fails (patch 7)
> - 3 tests are no longer skipped (patch 4)
> - More accurate return values for whole suites (patch 8, 9)
> - Extra tests are more likely to be built (patch 1-3)
Updated, thanks.
> ---
> v2..v3:
> - Patch 5: new patch [David Hildenbrand]
> - Patch 6: make the helper take a number of pages + pagesize, rename to
> force_read_pages() [David]
> - Patch 7: improved page count calculation (avoiding floating-point
> helper)
> - Patch 7: added Fixes tag [David]
> - Patch 9: open the file only once and save the fd [David]
> - Collected R-b/A-b
>
Below is how v3 altered mm.git:
--- a/tools/testing/selftests/mm/cow.c~b
+++ a/tools/testing/selftests/mm/cow.c
@@ -75,6 +75,18 @@ static bool range_is_swapped(void *addr,
return true;
}
+static bool populate_page_checked(char *addr)
+{
+ bool ret;
+
+ FORCE_READ(*addr);
+ ret = pagemap_is_populated(pagemap_fd, addr);
+ if (!ret)
+ ksft_print_msg("Failed to populate page\n");
+
+ return ret;
+}
+
struct comm_pipes {
int child_ready[2];
int parent_ready[2];
@@ -1549,8 +1561,10 @@ static void run_with_zeropage(non_anon_t
}
/* Read from the page to populate the shared zeropage. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, pagesize);
munmap:
@@ -1612,8 +1626,11 @@ static void run_with_huge_zeropage(non_a
* the first sub-page and test if we get another sub-page populated
* automatically.
*/
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
+
if (!pagemap_is_populated(pagemap_fd, mem + pagesize) ||
!pagemap_is_populated(pagemap_fd, smem + pagesize)) {
ksft_test_result_skip("Did not get THPs populated\n");
@@ -1663,8 +1680,10 @@ static void run_with_memfd(non_anon_test
}
/* Fault the page in. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, pagesize);
munmap:
@@ -1719,8 +1738,10 @@ static void run_with_tmpfile(non_anon_te
}
/* Fault the page in. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, pagesize);
munmap:
@@ -1773,8 +1794,10 @@ static void run_with_memfd_hugetlb(non_a
}
/* Fault the page in. */
- FORCE_READ(*mem);
- FORCE_READ(*smem);
+ if (!populate_page_checked(mem) || !populate_page_checked(smem)) {
+ log_test_result(KSFT_FAIL);
+ goto munmap;
+ }
fn(mem, smem, hugetlbsize);
munmap:
--- a/tools/testing/selftests/mm/hugetlb-madvise.c~b
+++ a/tools/testing/selftests/mm/hugetlb-madvise.c
@@ -47,7 +47,7 @@ void write_fault_pages(void *addr, unsig
void read_fault_pages(void *addr, unsigned long nr_pages)
{
- force_read_pages_in_range(addr, nr_pages * huge_page_size);
+ force_read_pages(addr, nr_pages, huge_page_size);
}
int main(int argc, char **argv)
--- a/tools/testing/selftests/mm/pagemap_ioctl.c~b
+++ a/tools/testing/selftests/mm/pagemap_ioctl.c
@@ -1052,7 +1052,7 @@ static void test_simple(void)
int sanity_tests(void)
{
unsigned long long mem_size, vec_size;
- long ret, fd, i, buf_size;
+ long ret, fd, i, buf_size, nr_pages;
struct page_region *vec;
char *mem, *fmem;
struct stat sbuf;
@@ -1166,13 +1166,14 @@ int sanity_tests(void)
if (fmem == MAP_FAILED)
ksft_exit_fail_msg("error nomem %d %s\n", errno, strerror(errno));
- force_read_pages_in_range(fmem, sbuf.st_size);
+ nr_pages = (sbuf.st_size + page_size - 1) / page_size;
+ force_read_pages(fmem, nr_pages, page_size);
ret = pagemap_ioctl(fmem, sbuf.st_size, vec, vec_size, 0, 0,
0, PAGEMAP_NON_WRITTEN_BITS, 0, PAGEMAP_NON_WRITTEN_BITS);
ksft_test_result(ret >= 0 && vec[0].start == (uintptr_t)fmem &&
- LEN(vec[0]) == ceilf((float)sbuf.st_size/page_size) &&
+ LEN(vec[0]) == nr_pages &&
(vec[0].categories & PAGE_IS_FILE),
"%s Memory mapped file\n", __func__);
--- a/tools/testing/selftests/mm/pfnmap.c~b
+++ a/tools/testing/selftests/mm/pfnmap.c
@@ -30,13 +30,14 @@
static sigjmp_buf sigjmp_buf_env;
static char *file = "/dev/mem";
static off_t file_offset;
+static int fd;
static void signal_handler(int sig)
{
siglongjmp(sigjmp_buf_env, -EFAULT);
}
-static int test_read_access(char *addr, size_t size)
+static int test_read_access(char *addr, size_t size, size_t pagesize)
{
int ret;
@@ -45,7 +46,7 @@ static int test_read_access(char *addr,
ret = sigsetjmp(sigjmp_buf_env, 1);
if (!ret)
- force_read_pages_in_range(addr, size);
+ force_read_pages(addr, size/pagesize, pagesize);
if (signal(SIGSEGV, SIG_DFL) == SIG_ERR)
return -EINVAL;
@@ -104,7 +105,6 @@ static void pfnmap_init(void)
{
size_t pagesize = getpagesize();
size_t size = DEV_MEM_NPAGES * pagesize;
- int fd;
void *addr;
if (strncmp(file, "/dev/mem", strlen("/dev/mem")) == 0) {
@@ -117,16 +117,16 @@ static void pfnmap_init(void)
file_offset = 0;
}
- /*
- * Make sure we can open and map the file, and perform some basic
- * checks; skip the whole suite if anything goes wrong.
- * A fresh mapping is then created for every test case by
- * FIXTURE_SETUP(pfnmap).
- */
fd = open(file, O_RDONLY);
if (fd < 0)
ksft_exit_skip("Cannot open '%s': %s\n", file, strerror(errno));
+ /*
+ * Make sure we can map the file, and perform some basic checks; skip
+ * the whole suite if anything goes wrong.
+ * A fresh mapping is then created for every test case by
+ * FIXTURE_SETUP(pfnmap).
+ */
addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, file_offset);
if (addr == MAP_FAILED)
ksft_exit_skip("Cannot mmap '%s': %s\n", file, strerror(errno));
@@ -134,17 +134,15 @@ static void pfnmap_init(void)
if (!check_vmflag_pfnmap(addr))
ksft_exit_skip("Invalid file: '%s'. Not pfnmap'ed\n", file);
- if (test_read_access(addr, size))
+ if (test_read_access(addr, size, pagesize))
ksft_exit_skip("Cannot read-access mmap'ed '%s'\n", file);
munmap(addr, size);
- close(fd);
}
FIXTURE(pfnmap)
{
size_t pagesize;
- int dev_mem_fd;
char *addr1;
size_t size1;
char *addr2;
@@ -155,12 +153,9 @@ FIXTURE_SETUP(pfnmap)
{
self->pagesize = getpagesize();
- self->dev_mem_fd = open(file, O_RDONLY);
- ASSERT_GE(self->dev_mem_fd, 0);
-
self->size1 = DEV_MEM_NPAGES * self->pagesize;
self->addr1 = mmap(NULL, self->size1, PROT_READ, MAP_SHARED,
- self->dev_mem_fd, file_offset);
+ fd, file_offset);
ASSERT_NE(self->addr1, MAP_FAILED);
self->size2 = 0;
@@ -173,8 +168,6 @@ FIXTURE_TEARDOWN(pfnmap)
munmap(self->addr2, self->size2);
if (self->addr1 != MAP_FAILED)
munmap(self->addr1, self->size1);
- if (self->dev_mem_fd >= 0)
- close(self->dev_mem_fd);
}
TEST_F(pfnmap, madvise_disallowed)
@@ -214,7 +207,7 @@ TEST_F(pfnmap, munmap_split)
*/
self->size2 = self->pagesize;
self->addr2 = mmap(NULL, self->pagesize, PROT_READ, MAP_SHARED,
- self->dev_mem_fd, file_offset);
+ fd, file_offset);
ASSERT_NE(self->addr2, MAP_FAILED);
}
@@ -265,7 +258,8 @@ TEST_F(pfnmap, fork)
ASSERT_GE(pid, 0);
if (!pid) {
- EXPECT_EQ(test_read_access(self->addr1, self->size1), 0);
+ EXPECT_EQ(test_read_access(self->addr1, self->size1,
+ self->pagesize), 0);
exit(0);
}
--- a/tools/testing/selftests/mm/split_huge_page_test.c~b
+++ a/tools/testing/selftests/mm/split_huge_page_test.c
@@ -652,7 +652,7 @@ static int create_pagecache_thp_and_fd(c
}
madvise(*addr, fd_size, MADV_HUGEPAGE);
- force_read_pages_in_range(*addr, fd_size);
+ force_read_pages(*addr, fd_size / pmd_pagesize, pmd_pagesize);
if (!check_huge_file(*addr, fd_size / pmd_pagesize, pmd_pagesize)) {
ksft_print_msg("No large pagecache folio generated, please provide a filesystem supporting large folio\n");
--- a/tools/testing/selftests/mm/vm_util.h~b
+++ a/tools/testing/selftests/mm/vm_util.h
@@ -54,10 +54,11 @@ static inline unsigned int pshift(void)
return __page_shift;
}
-static inline void force_read_pages_in_range(char *addr, size_t len)
+static inline void force_read_pages(char *addr, unsigned int nr_pages,
+ size_t pagesize)
{
- for (size_t i = 0; i < len; i += psize())
- FORCE_READ(addr[i]);
+ for (unsigned int i = 0; i < nr_pages; i++)
+ FORCE_READ(addr[i * pagesize]);
}
bool detect_huge_zeropage(void);
_
^ permalink raw reply [flat|nested] 20+ messages in thread