• Lorenzo Stoakes's avatar
    mm: avoid using vma_merge() for new VMAs · cacded5e
    Lorenzo Stoakes authored
    Abstract vma_merge_new_vma() to use vma_merge_struct and rename the
    resultant function vma_merge_new_range() to be clear what the purpose of
    this function is - a new VMA is desired in the specified range, and we
    wish to see if it is possible to 'merge' surrounding VMAs into this range
    rather than having to allocate a new VMA.
    
    Note that this function uses vma_extend() exclusively, so adopts its
    requirement that the iterator point at or before the gap.  We add an
    assert to this effect.
    
    This is as opposed to vma_merge_existing_range(), which will be introduced
    in a subsequent commit, and provide the same functionality for cases in
    which we are modifying an existing VMA.
    
    In mmap_region() and do_brk_flags() we open code scenarios where we prefer
    to use vma_expand() rather than invoke a full vma_merge() operation.
    
    Abstract this logic and eliminate all of the open-coding, and also use the
    same logic for all cases where we add new VMAs to, rather than ultimately
    use vma_merge(), rather use vma_expand().
    
    Doing so removes duplication and simplifies VMA merging in all such cases,
    laying the ground for us to eliminate the merging of new VMAs in
    vma_merge() altogether.
    
    Also add the ability for the vmg to track state, and able to report
    errors, allowing for us to differentiate a failed merge from an inability
    to allocate memory in callers.
    
    This makes it far easier to understand what is happening in these cases
    avoiding confusion, bugs and allowing for future optimisation.
    
    Also introduce vma_iter_next_rewind() to allow for retrieval of the next,
    and (optionally) the prev VMA, rewinding to the start of the previous gap.
    
    Introduce are_anon_vmas_compatible() to abstract individual VMA anon_vma
    comparison for the case of merging on both sides where the anon_vma of the
    VMA being merged maybe compatible with prev and next, but prev and next's
    anon_vma's may not be compatible with each other.
    
    Finally also introduce can_vma_merge_left() / can_vma_merge_right() to
    check adjacent VMA compatibility and that they are indeed adjacent.
    
    Link: https://lkml.kernel.org/r/49d37c0769b6b9dc03b27fe4d059173832556392.1725040657.git.lorenzo.stoakes@oracle.comSigned-off-by: default avatarLorenzo Stoakes <lorenzo.stoakes@oracle.com>
    Tested-by: default avatarMark Brown <broonie@kernel.org>
    Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Cc: Bert Karwatzki <spasswolf@web.de>
    Cc: Jeff Xu <jeffxu@chromium.org>
    Cc: Jiri Olsa <olsajiri@gmail.com>
    Cc: Kees Cook <kees@kernel.org>
    Cc: Lorenzo Stoakes <lstoakes@gmail.com>
    Cc: Matthew Wilcox <willy@infradead.org>
    Cc: "Paul E. McKenney" <paulmck@kernel.org>
    Cc: Paul Moore <paul@paul-moore.com>
    Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
    Cc: Suren Baghdasaryan <surenb@google.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    cacded5e
vma_internal.h 21.5 KB