Re: [PATCH v3 08/15] mm: introduce and use linear_folio_page_index()

"David Hildenbrand (Arm)" <[email protected]>
Newsgroups gmane.linux.kernel,gmane.linux.kernel.mm,gmane.linux.file-systems
Message-ID <[email protected]>
On 7/29/26 18:48, Lorenzo Stoakes (ARM) wrote:
> This function is, for now, a placeholder; it will be used in future to
> determine whether to use the anonymous page index or not, based on whether
> the folio is anonymous or not.
> 
> Currently it simply wraps linear_page_index(), so this does not change
> behaviour.
> 
> We update callers that will, once the change is introduced to track
> anonymous folios by anonymous page offset if MAP_PRIVATE file-backed, need
> to determine which index to use based on folio type.
> 
> No functional change intended.
> 
> Signed-off-by: Lorenzo Stoakes (ARM) <[email protected]>
> ---
>  include/linux/pagemap.h | 18 ++++++++++++++++++
>  mm/huge_memory.c        |  3 ++-
>  mm/migrate.c            |  6 ++++--
>  mm/userfaultfd.c        |  6 ++++--
>  4 files changed, 28 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index 259177544b03..6eb8d811ba4c 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -1143,6 +1143,24 @@ static inline pgoff_t linear_anon_page_index(const struct vm_area_struct *vma,
>  	return pgoff;
>  }
>  
> +/**
> + * linear_folio_page_index() - Determine the absolute page offset of
> + * @address within @vma from @folio.
> + * @folio: The folio whose linear page index is sought.
> + * @vma: The VMA in which @address resides.
> + * @address: The address whose absolute page offset is required.
> + *
> + * For compatibility, currently identical to linear_page_index().
> + *
> + * Returns: The absolute page offset of @address within @vma.
> + */
> +static inline pgoff_t linear_folio_page_index(const struct folio *folio,
> +					      const struct vm_area_struct *vma,
> +					      const unsigned long address)
> +{
> +	return linear_page_index(vma, address);
> +}


I found this to be rather confusing, given that we now have a "folio" helper that
receives a folio and a "page" helper that doesn't receive a page ...

I guess the problem is the "page" in "linear_page_index", as it
reminds of legacy page->index.


I wonder if it would be better to have a linear_folio_index() and
force that address points at the start of the folio.

Looking below, this is exactly what we want for all except one case:


>  		/* pgoff is invalid for ksm pages, but they are never large */
> -		if (folio_test_large(folio) && !folio_test_hugetlb(folio))
> -			idx = linear_page_index(vma, pvmw.address) - pvmw.pgoff;
> +		if (folio_test_large(folio) && !folio_test_hugetlb(folio)) {
> +			idx += linear_folio_page_index(folio, vma, pvmw.address);
> +			idx -= pvmw.pgoff;
> +		}
>  		new = folio_page(folio, idx);

I think we could avoid this index work entirely by using the pfn, which is much
clearer to me, and similar to how we handle it during other rmap operations.

diff --git a/mm/migrate.c b/mm/migrate.c
index 222c8c15f782f..686351d353203 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -362,17 +362,12 @@ static bool remove_migration_pte(struct folio *folio,
                struct page *new;
                unsigned long idx = 0;

-               /* pgoff is invalid for ksm pages, but they are never large */
-               if (folio_test_large(folio) && !folio_test_hugetlb(folio))
-                       idx = linear_page_index(vma, pvmw.address) - pvmw.pgoff;
-               new = folio_page(folio, idx);
-
 #ifdef CONFIG_ARCH_HAS_PMD_SOFTLEAVES
                /* PMD-mapped THP migration entry */
                if (!pvmw.pte) {
                        VM_BUG_ON_FOLIO(folio_test_hugetlb(folio) ||
                                        !folio_test_pmd_mappable(folio), folio);
-                       remove_migration_pmd(&pvmw, new);
+                       remove_migration_pmd(&pvmw, folio_page(folio, idx));
                        continue;
                }
 #endif
@@ -385,10 +380,14 @@ static bool remove_migration_pte(struct folio *folio,
                    try_to_map_unused_to_zeropage(&pvmw, folio, old_pte, idx))
                        continue;

+               entry = softleaf_from_pte(old_pte);
+               if (folio_test_large(folio) && !folio_test_hugetlb(folio))
+                       idx = softleaf_to_pfn(entry) - folio_pfn(rmap_walk_arg->folio);
+               new = folio_page(folio, idx);
+
                folio_get(folio);
                pte = mk_pte(new, READ_ONCE(vma->vm_page_prot));

-               entry = softleaf_from_pte(old_pte);
                if (!softleaf_is_migration_young(entry))
                        pte = pte_mkold(pte);
                if (folio_test_dirty(folio) && softleaf_is_migration_dirty(entr


remove_migration_pmd() will work for now. Later it should just receive the folio
and do the same thing through softleaf_from_pmd() -> softleaf_to_pfn().

-- 
Cheers,

David
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.