Extract address space limit check for overlapped regions
in a separate helper.

v2: New

Signed-off-by: Kirill Tkhai <[email protected]>
---
 mm/mmap.c |   33 ++++++++++++++++++++-------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/mm/mmap.c b/mm/mmap.c
index e4ced5366643..260e47e917e6 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -583,6 +583,24 @@ static unsigned long count_vma_pages_range(struct 
mm_struct *mm,
        return nr_pages;
 }
 
+/*
+ * Check against address space limit, whether we may expand mm
+ * with a new mapping. Currently mapped in the given range pages
+ * are not accounted in the limit.
+ */
+static bool may_mmap_overlapped_region(struct mm_struct *mm,
+               unsigned long vm_flags, unsigned long addr, unsigned long len)
+{
+       unsigned long nr_pages = len >> PAGE_SHIFT;
+
+       if (!may_expand_vm(mm, vm_flags, nr_pages)) {
+               nr_pages -= count_vma_pages_range(mm, addr, addr + len);
+               if (!may_expand_vm(mm, vm_flags, nr_pages))
+                       return false;
+       }
+       return true;
+}
+
 void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
                struct rb_node **rb_link, struct rb_node *rb_parent)
 {
@@ -1697,19 +1715,8 @@ unsigned long mmap_region(struct file *file, unsigned 
long addr,
        unsigned long charged = 0;
 
        /* Check against address space limit. */
-       if (!may_expand_vm(mm, vm_flags, len >> PAGE_SHIFT)) {
-               unsigned long nr_pages;
-
-               /*
-                * MAP_FIXED may remove pages of mappings that intersects with
-                * requested mapping. Account for the pages it would unmap.
-                */
-               nr_pages = count_vma_pages_range(mm, addr, addr + len);
-
-               if (!may_expand_vm(mm, vm_flags,
-                                       (len >> PAGE_SHIFT) - nr_pages))
-                       return -ENOMEM;
-       }
+       if (!may_mmap_overlapped_region(mm, vm_flags, addr, len))
+               return -ENOMEM;
 
        /* Clear old maps */
        while (find_vma_links(mm, addr, addr + len, &prev, &rb_link,

Reply via email to