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