As there is no longer a vmacache, find_vma() is more expensive and so
avoid doing them

Signed-off-by: Liam R. Howlett <[email protected]>
---
 mm/mmap.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index c3ac4d6f970d3..15616f105d051 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2720,7 +2720,6 @@ int __do_munmap(struct mm_struct *mm, unsigned long 
start, size_t len,
        if (!vma)
                return 0;
 
-       prev = vma->vm_prev;
        /* we have start < vma->vm_end  */
 
        /*
@@ -2744,16 +2743,24 @@ int __do_munmap(struct mm_struct *mm, unsigned long 
start, size_t len,
                if (error)
                        return error;
                prev = vma;
+               vma = vma_next(mm, prev);
+       } else {
+               prev = vma->vm_prev;
        }
 
+       if (vma->vm_end >= end)
+               last = vma;
+       else
+               last = find_vma_intersection(mm, end - 1, end);
+
        /* Does it split the last one? */
-       last = find_vma(mm, end);
-       if (last && end > last->vm_start) {
+       if (last && end < last->vm_end) {
                int error = __split_vma(mm, last, end, 1);
                if (error)
                        return error;
+               vma = vma_next(mm, prev);
        }
-       vma = vma_next(mm, prev);
+
 
        if (unlikely(uf)) {
                /*
@@ -2766,6 +2773,7 @@ int __do_munmap(struct mm_struct *mm, unsigned long 
start, size_t len,
                 * failure that it's not worth optimizing it for.
                 */
                int error = userfaultfd_unmap_prep(vma, start, end, uf);
+
                if (error)
                        return error;
        }
-- 
2.28.0

Reply via email to