Re: [PATCH 01/15] mm/vma: introduce VMA virtual page offset field and add helpers
From: xu.xin16
Date: Sat Jul 18 2026 - 23:56:03 EST
> This patch establishes fields within the vm_area_struct type to store the
> virtual page offset of VMAs.
>
> The virtual page offset of a VMA is equal to vma->vm_start >> PAGE_SHIFT if
> they are unfaulted or were not remapped, otherwise it is equal to this
> value at the point of first fault.
>
> Currently, anonymous folios belonging to CoW'd MAP_PRIVATE-mapped
> file-backed VMAs are tracked by their file offset. By adding virtual offset
> as a property of VMAs, we can now track them by their virtual page offset
> instead.
>
> By tracking this, we provide the means by which to eliminate this
> inconsistency, and more importantly lay the foundations for future work for
> the scalable CoW anonymous rmap rework.
>
> This patch simply adds the fields and some simple helpers. Subsequent
> patches will update mm code to make use of these fields correctly.
>
> The fields chosen are packed in the VMA such that, for 64-bit kernel
> builds, no additional space is taken up.
It is not necessarily true that no additional memory will be consumed, as it
depends on whether the baseline kernel has CONFIG_PER_VMA_LOCK enabled.
Moreover, in the future evolution of mm, maintaining this benefit would
require that the layout of struct vm_area_struct before __vm_virt_pgoff_lo
remains unchanged, which seems impractical.
My personal suggestion is: maybe we could simply add an unsigned long field,
say vm_virt_pgoff, without worrying about the increased memory footprint for
now. Additionally, it would be helpful to add some comments clarifying the
difference between this new field and the existing vm_pgoff, to aid understanding.
Thanks,
Xu Xin
>
> The first field is present on cacheline 0 containing key VMA fields, and
> the second on cacheline 3, which contains file-backed reverse mapping
> fields.
>
>
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@xxxxxxxxxx>
> ---
> include/linux/mm.h | 59 +++++++++++++++++++++++++++++++++++++++++
> include/linux/mm_types.h | 4 +++
> mm/vma.h | 14 ++++++++++
> mm/vma_init.c | 1 +
> tools/testing/vma/include/dup.h | 26 ++++++++++++++++++
> 5 files changed, 104 insertions(+)
>
> +static inline pgoff_t vma_last_virt_pgoff(const struct vm_area_struct *vma)
> +{
> + return vma_end_virt_pgoff(vma) - 1;
> +}
> +
> static inline unsigned long vma_desc_size(const struct vm_area_desc *desc)
> {
> return desc->end - desc->start;
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 939b5ea8c9e0..2710628059b1 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -967,6 +967,7 @@ struct vm_area_struct {
> */
> unsigned int vm_lock_seq;
> #endif
> + unsigned int __vm_virt_pgoff_lo; /* Low 32-bits of virtual pgoff. */
> /*
> * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
> * list, after a COW of one of the file pages. A MAP_SHARED vma
> @@ -1041,6 +1042,9 @@ struct vm_area_struct {
> #ifdef CONFIG_DEBUG_LOCK_ALLOC
> struct lockdep_map vmlock_dep_map;
> #endif
> +#endif
> +#ifdef CONFIG_64BIT
> + unsigned int __vm_virt_pgoff_hi; /* High 32-bits of virtual pgoff. */
> #endif
>