Re: [PATCH v2 13/33] mm/vma: introduce and use vmg_pages(), vmg_[start, end]_pgoff()
From: Lorenzo Stoakes (ARM)
Date: Tue Jul 14 2026 - 06:17:57 EST
On Mon, Jul 13, 2026 at 08:12:24PM +0200, Vlastimil Babka (SUSE) wrote:
> On 7/10/26 22:16, Lorenzo Stoakes wrote:
> > In the VMA logic we often need to determine the number of pages in the
> > specified merge range, as well as the start and end page offsets of that
> > range.
> >
> > Introduce and use helpers for these purposes.
> >
> > No functional change intended.
> >
> > Reviewed-by: Pedro Falcato <pfalcato@xxxxxxx>
> > Reviewed-by: Gregory Price <gourry@xxxxxxxxxx>
> > Signed-off-by: Lorenzo Stoakes <ljs@xxxxxxxxxx>
>
> Uh, the PHYS_PFN() usage here was quite an abuse. Good riddance.
Yeah and mine :)) but absolutely agree it was wrong and glad to fix my own
mistake in using that ;)
> Reviewed-by: Vlastimil Babka (SUSE) <vbabka@xxxxxxxxxx>
Thanks!
>
> > ---
> > mm/vma.c | 11 ++++-------
> > mm/vma.h | 17 +++++++++++++++++
> > 2 files changed, 21 insertions(+), 7 deletions(-)
> >
> > diff --git a/mm/vma.c b/mm/vma.c
> > index 35ba3475128f..995de8198fbb 100644
> > --- a/mm/vma.c
> > +++ b/mm/vma.c
> > @@ -197,11 +197,9 @@ static void init_multi_vma_prep(struct vma_prepare *vp,
> > */
> > static bool can_vma_merge_before(struct vma_merge_struct *vmg)
> > {
> > - pgoff_t pglen = PHYS_PFN(vmg->end - vmg->start);
> > -
> > if (is_mergeable_vma(vmg, /* merge_next = */ true) &&
> > is_mergeable_anon_vma(vmg, /* merge_next = */ true)) {
> > - if (vmg->next->vm_pgoff == vmg->pgoff + pglen)
> > + if (vmg_end_pgoff(vmg) == vma_start_pgoff(vmg->next))
> > return true;
> > }
> >
> > @@ -221,7 +219,7 @@ static bool can_vma_merge_after(struct vma_merge_struct *vmg)
> > {
> > if (is_mergeable_vma(vmg, /* merge_next = */ false) &&
> > is_mergeable_anon_vma(vmg, /* merge_next = */ false)) {
> > - if (vmg->prev->vm_pgoff + vma_pages(vmg->prev) == vmg->pgoff)
> > + if (vma_end_pgoff(vmg->prev) == vmg_start_pgoff(vmg))
> > return true;
> > }
> > return false;
> > @@ -759,7 +757,7 @@ static int commit_merge(struct vma_merge_struct *vmg)
> > */
> > vma_adjust_trans_huge(vma, vmg->start, vmg->end,
> > vmg->__adjust_middle_start ? vmg->middle : NULL);
> > - vma_set_range(vma, vmg->start, vmg->end, vmg->pgoff);
> > + vma_set_range(vma, vmg->start, vmg->end, vmg_start_pgoff(vmg));
> > vmg_adjust_set_range(vmg);
> > vma_iter_store_overwrite(vmg->vmi, vmg->target);
> >
> > @@ -962,8 +960,7 @@ static __must_check struct vm_area_struct *vma_merge_existing_range(
> > * middle next
> > * shrink/delete extend
> > */
> > -
> > - pgoff_t pglen = PHYS_PFN(vmg->end - vmg->start);
> > + const pgoff_t pglen = vmg_pages(vmg);
> >
> > VM_WARN_ON_VMG(!merge_right, vmg);
> > /* If we are offset into a VMA, then prev must be middle. */
> > diff --git a/mm/vma.h b/mm/vma.h
> > index 8e4b61a7304c..527716c8739d 100644
> > --- a/mm/vma.h
> > +++ b/mm/vma.h
> > @@ -230,6 +230,23 @@ static inline bool vmg_nomem(struct vma_merge_struct *vmg)
> > return vmg->state == VMA_MERGE_ERROR_NOMEM;
> > }
> >
> > +static inline pgoff_t vmg_start_pgoff(const struct vma_merge_struct *vmg)
> > +{
> > + return vmg->pgoff;
> > +}
> > +
> > +static inline pgoff_t vmg_pages(const struct vma_merge_struct *vmg)
> > +{
> > + const unsigned long size = vmg->end - vmg->start;
> > +
> > + return size >> PAGE_SHIFT;
> > +}
> > +
> > +static inline pgoff_t vmg_end_pgoff(const struct vma_merge_struct *vmg)
> > +{
> > + return vmg_start_pgoff(vmg) + vmg_pages(vmg);
> > +}
> > +
> > /* Assumes addr >= vma->vm_start. */
> > static inline pgoff_t vma_pgoff_offset(struct vm_area_struct *vma,
> > unsigned long addr)
> >
>
Cheers, Lorenzo