On Sat, Aug 15, 2026 at 02:58:50AM +0100, Kiryl Shutsemau wrote:
> From: "Kiryl Shutsemau (Meta)" <[email protected]>
>
> An mTHP collapse test needs to know that a range is backed by folios of the
> target order, and that they sit where a collapse would put them. Nothing
> answers that today: is_backed_by_folio() classifies the folio behind a
> single page, and check_huge_anon() reads smaps AnonHugePages, which only
> accounts PMD mappings.
>
> Add is_range_backed_by_folio_orders(). For every order-aligned window of
> the range it requires a present head PFN at its natural alignment and a
> contiguous PFN run across the window.
>
> A window backed by two smaller folios fails the contiguity check, and a
> folio mapped off the window's alignment fails the head check. The mTHP
> cases need both to tell a collapsed window from the one beside it.
>
> Assisted-by: Claude-Code:claude-opus-5
> Tested-by: Muhammad Usama Anjum <[email protected]>
> Signed-off-by: Kiryl Shutsemau (Meta) <[email protected]>
> ---
> tools/testing/selftests/mm/vm_util.c | 42 ++++++++++++++++++++++++++++
> tools/testing/selftests/mm/vm_util.h | 2 ++
> 2 files changed, 44 insertions(+)
>
> diff --git a/tools/testing/selftests/mm/vm_util.c
> b/tools/testing/selftests/mm/vm_util.c
> index 5db1a7774f49..c9bd6c92fa41 100644
> --- a/tools/testing/selftests/mm/vm_util.c
> +++ b/tools/testing/selftests/mm/vm_util.c
> @@ -556,6 +556,48 @@ bool is_backed_by_folio(char *vaddr, int order, int
> pagemap_fd,
> return false;
> }
>
> +/*
> + * Check whether every order-@order window of [start, len) maps exactly one
Strange to reference @order in a non-kdoc comment. And then to start referring
to start and len without @? :)
And I'm not sure 'window' is really clear here as a term...
> + * folio of that order, head to tail. The address range must be naturally
> + * aligned, each window's PFN run must be contiguous, and a window's first
> + * PFN must be the folio head.
Also 'PFN run' is adding a new vague term.
> + *
> + * This is the check "did this range collapse into order-@order folios": a
> + * window assembled from parts of several folios, or mapping a folio shifted
> + * from its natural position, fails.
I think you could simplify this to something like:
Check that the buffer @start of @len bytes is mTHP-backed by @order
folios wholly contained within the range.
This requires that @buffer is aligned to @order and that every folio
is fully contained head-to-tail.
Returns: true if wholly mTHP backed, false otherwise.
> + */
> +bool is_range_backed_by_folio_orders(char *start, size_t len, int order,
is_range_mthp_backed() seems a lot clearer?
> + int pagemap_fd, int kpageflags_fd)
> +{
> + const unsigned long nr_pages = 1UL << order;
> + const size_t window = nr_pages * psize();
folio_size seems clearer?
> + char *vaddr;
> +
> + if ((uintptr_t)start % window || len % window)
> + return false;
> +
> + for (vaddr = start; vaddr < start + len; vaddr += window) {
> + unsigned long pfn = pagemap_get_pfn(pagemap_fd, vaddr);
NIT: can const-ify.
> + unsigned long i;
> +
> + /* Not present, or not mapping the folio head. */
'Or a tail page' maybe?
> + if (pfn == -1UL || pfn % nr_pages)
> + return false;
> +
> + for (i = 1; i < nr_pages; i++) {
> + if (pagemap_get_pfn(pagemap_fd, vaddr + i * psize()) !=
> + pfn + i)
> + return false;
> + }
NIT: can drop the {}.
> +
> + if (!is_backed_by_folio(vaddr, order, pagemap_fd,
> + kpageflags_fd))
> + return false;
> + }
> +
> + return true;
> +}
> +
> /* If `ioctls' non-NULL, the allowed ioctls will be returned into the var */
> int uffd_register_with_ioctls(int uffd, void *addr, uint64_t len,
> bool miss, bool wp, bool minor, uint64_t *ioctls)
> diff --git a/tools/testing/selftests/mm/vm_util.h
> b/tools/testing/selftests/mm/vm_util.h
> index 56a28ce7d029..39dfb18dc10c 100644
> --- a/tools/testing/selftests/mm/vm_util.h
> +++ b/tools/testing/selftests/mm/vm_util.h
> @@ -99,6 +99,8 @@ int gather_folio_orders(char *vaddr_start, size_t len,
> int pagemap_fd, int kpageflags_fd, int orders[], int nr_orders);
> bool is_backed_by_folio(char *vaddr, int order, int pagemap_fd,
> int kpageflags_fd);
> +bool is_range_backed_by_folio_orders(char *start, size_t len, int order,
> + int pagemap_fd, int kpageflags_fd);
>
> int uffd_register(int uffd, void *addr, uint64_t len,
> bool miss, bool wp, bool minor);
> --
> 2.54.0
>
--
Cheers, Lorenzo