> 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) <[email protected]>
> ---
>  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
>

Reply via email to