On Mon, Jun 29, 2026 at 01:23:32PM +0100, Lorenzo Stoakes wrote: > Add helpers for adding or subtracting to a VMA's page offset, exposed > internally for VMA users within mm in mm/vma.h. > > This is to lay the foundations for tracking anonymous page offset for > MAP_PRIVATE file-backed mappings, where adding and subtracting from this > value must be reflected in both the file and anonymous offsets. > > These are used on VMA split and downward stack expansion. > > No functional change intended. > > Signed-off-by: Lorenzo Stoakes <[email protected]> > --- > mm/nommu.c | 6 ++++-- > mm/vma.c | 6 +++--- > mm/vma.h | 12 ++++++++++++ > tools/testing/vma/include/dup.h | 13 ++++++++++++- > 4 files changed, 31 insertions(+), 6 deletions(-) > > diff --git a/mm/nommu.c b/mm/nommu.c > index 7333d855e974..c7fafcd87c14 100644 > --- a/mm/nommu.c > +++ b/mm/nommu.c > @@ -41,6 +41,7 @@ > #include <asm/tlbflush.h> > #include <asm/mmu_context.h> > #include "internal.h" > +#include "vma.h" > > unsigned long highest_memmap_pfn; > int heap_stack_gap = 0; > @@ -1338,7 +1339,8 @@ static int split_vma(struct vma_iterator *vmi, struct > vm_area_struct *vma, > region->vm_top = region->vm_end = new->vm_end = addr; > } else { > region->vm_start = new->vm_start = addr; > - region->vm_pgoff = new->vm_pgoff += npages; > + vma_add_pgoff(new, npages); > + region->vm_pgoff = vma_start_pgoff(new); > } > > vma_iter_config(vmi, new->vm_start, new->vm_end); > @@ -1355,7 +1357,7 @@ static int split_vma(struct vma_iterator *vmi, struct > vm_area_struct *vma, > delete_nommu_region(vma->vm_region); > if (new_below) { > vma->vm_region->vm_start = vma->vm_start = addr; > - vma->vm_pgoff += npages; > + vma_add_pgoff(vma, npages); > vma->vm_region->vm_pgoff = vma_start_pgoff(vma); > } else { > vma->vm_region->vm_end = vma->vm_end = addr; > diff --git a/mm/vma.c b/mm/vma.c > index 185d07397ca6..cb7222e20c93 100644 > --- a/mm/vma.c > +++ b/mm/vma.c > @@ -517,7 +517,7 @@ __split_vma(struct vma_iterator *vmi, struct > vm_area_struct *vma, > new->vm_end = addr; > } else { > new->vm_start = addr; > - new->vm_pgoff += linear_page_delta(vma, addr); > + vma_add_pgoff(new, linear_page_delta(vma, addr)); > } > > err = -ENOMEM; > @@ -556,7 +556,7 @@ __split_vma(struct vma_iterator *vmi, struct > vm_area_struct *vma, > > if (new_below) { > vma->vm_start = addr; > - vma->vm_pgoff += (addr - new->vm_start) >> PAGE_SHIFT; > + vma_add_pgoff(vma, (addr - new->vm_start) >> PAGE_SHIFT); > } else { > vma->vm_end = addr; > } > @@ -3305,7 +3305,7 @@ int expand_downwards(struct vm_area_struct *vma, > unsigned long address) > vm_stat_account(mm, vma->vm_flags, grow); > anon_vma_interval_tree_pre_update_vma(vma); > vma->vm_start = address; > - vma->vm_pgoff -= grow; > + vma_sub_pgoff(vma, grow); > /* Overwrite old entry in mtree. */ > vma_iter_store_overwrite(&vmi, vma); > anon_vma_interval_tree_post_update_vma(vma); > diff --git a/mm/vma.h b/mm/vma.h > index 2342516ce00e..47fe35e5307e 100644 > --- a/mm/vma.h > +++ b/mm/vma.h > @@ -247,6 +247,18 @@ static inline pgoff_t vmg_end_pgoff(const struct > vma_merge_struct *vmg) > return vmg_start_pgoff(vmg) + vmg_pages(vmg); > } > > +static inline void vma_add_pgoff(struct vm_area_struct *vma, pgoff_t delta) > +{ > + vma_assert_can_modify(vma); > + vma->vm_pgoff += delta; > +} > + > +static inline void vma_sub_pgoff(struct vm_area_struct *vma, pgoff_t delta) > +{ > + vma_assert_can_modify(vma); > + vma->vm_pgoff -= delta; > +} > + > #define VMG_STATE(name, mm_, vmi_, start_, end_, vma_flags_, pgoff_) \ > struct vma_merge_struct name = { \ > .mm = mm_, \ > diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h > index 7ed165c8d9bc..41fea90a344d 100644 > --- a/tools/testing/vma/include/dup.h > +++ b/tools/testing/vma/include/dup.h > @@ -1163,6 +1163,11 @@ static inline struct vm_area_struct *vma_next(struct > vma_iterator *vmi) > return mas_find(&vmi->mas, ULONG_MAX); > } > > +static inline bool vma_is_attached(struct vm_area_struct *vma) > +{ > + return refcount_read(&vma->vm_refcnt); > +} > + > /* > * WARNING: to avoid racing with vma_mark_attached()/vma_mark_detached(), > these > * assertions should be made either under mmap_write_lock or when the object > @@ -1170,7 +1175,13 @@ static inline struct vm_area_struct *vma_next(struct > vma_iterator *vmi) > */ > static inline void vma_assert_attached(struct vm_area_struct *vma) > { > - WARN_ON_ONCE(!refcount_read(&vma->vm_refcnt)); > + WARN_ON_ONCE(!vma_is_attached(vma)); > +} > + > +static inline void vma_assert_can_modify(struct vm_area_struct *vma) > +{ > + if (vma_is_attached(vma)) > + vma_assert_write_locked(vma); > }
These hunks in dup.h look lost. Should perhaps be on the previous patch (adding the helpers). Anyway, Obviously Correct(tm). Reviewed-by: Pedro Falcato <[email protected]> -- Pedro
