[PATCH v4 07/66] mm: Add VMA iterator

Liam Howlett liam.howlett at oracle.com
Thu Dec 9 18:02:58 PST 2021


* Vlastimil Babka <vbabka at suse.cz> [211209 10:26]:
> On 12/1/21 15:29, Liam Howlett wrote:
> > From: "Matthew Wilcox (Oracle)" <willy at infradead.org>
> > 
> > This thin layer of abstraction over the maple tree state is for
> > iterating over VMAs.  You can go forwards, go backwards or ask where
> > the iterator is.  Rename the existing vma_next() to __vma_next() --
> > it will be removed by the end of this series.
> > 
> > Signed-off-by: Matthew Wilcox (Oracle) <willy at infradead.org>
> > Signed-off-by: Liam R. Howlett <Liam.Howlett at Oracle.com>
> 
> Acked-by: Vlastimil Babka <vbabka at suse.cz>
> 
> With a question below.
> 
> > ---
> >  include/linux/mm.h       | 27 +++++++++++++++++++++++++++
> >  include/linux/mm_types.h | 21 +++++++++++++++++++++
> >  mm/mmap.c                | 10 +++++-----
> >  3 files changed, 53 insertions(+), 5 deletions(-)
> > 
> > diff --git a/include/linux/mm.h b/include/linux/mm.h
> > index 9eae78a155be..acdccbe9b96b 100644
> > --- a/include/linux/mm.h
> > +++ b/include/linux/mm.h
> > @@ -696,6 +696,33 @@ static inline bool vma_is_accessible(struct vm_area_struct *vma)
> >  	return vma->vm_flags & VM_ACCESS_FLAGS;
> >  }
> >  
> > +static inline
> > +struct vm_area_struct *vma_find(struct vma_iterator *vmi, unsigned long max)
> > +{
> > +	return mas_find(&vmi->mas, max);
> > +}
> > +
> > +static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi)
> > +{
> > +	return vma_find(vmi, ULONG_MAX);
> 
> Why not mas_next()?

vma_find() uses mas_find() which was created to implement find_vma().
As a replacement, the search looks for an entry at the address and if
nothing exists, it will continue the search upwards.  The result is that
the first entry can be found at the address passed.  Every subsequent
call to vma_find() would search from the end of the previous range - as
saved in the maple state, or the vma iterator in this case.

mas_next(), however is more of a traditional linked list operation that
finds the next entry _after_ the one containing the index in the maple
state.  The only difference is on the start when the maple state is not
currently pointing at an entry at all (the node is set to MAS_START).

mas_find() can be thought of as:

entry = mas_walk();
if (!entry)
	entry = mas_next_entry();

return entry;


mas_next can be though to as:

if (mas_is_start())
	mas_walk();

return mas_next_entry();


Matthew uses mas_find() for his implementation of the vma iterator so
that the first entry is not skipped.


> 
> > +}
> > +
> > +static inline struct vm_area_struct *vma_prev(struct vma_iterator *vmi)
> > +{
> > +	return mas_prev(&vmi->mas, 0);
> > +}
> > +
> > +static inline unsigned long vma_iter_addr(struct vma_iterator *vmi)
> > +{
> > +	return vmi->mas.index;
> > +}
> > +
> > +#define for_each_vma(vmi, vma)		while ((vma = vma_next(&vmi)) != NULL)
> > +


More information about the maple-tree mailing list