From: "Liam R. Howlett" <Liam.Howlett@Oracle.com>
To: maple-tree@lists.infradead.org, linux-mm@kvack.org,
linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@google.com>, Song Liu <songliubraving@fb.com>,
Davidlohr Bueso <dave@stgolabs.net>,
"Paul E . McKenney" <paulmck@kernel.org>,
Matthew Wilcox <willy@infradead.org>,
Jerome Glisse <jglisse@redhat.com>,
David Rientjes <rientjes@google.com>,
Axel Rasmussen <axelrasmussen@google.com>,
Suren Baghdasaryan <surenb@google.com>,
Vlastimil Babka <vbabka@suse.cz>, Rik van Riel <riel@surriel.com>,
Peter Zijlstra <peterz@infradead.org>
Subject: [PATCH v2 20/70] mm/mmap: Change __do_munmap() to avoid unnecessary lookups.
Date: Tue, 12 Jan 2021 11:11:50 -0500 [thread overview]
Message-ID: <20210112161240.2024684-21-Liam.Howlett@Oracle.com> (raw)
In-Reply-To: <20210112161240.2024684-1-Liam.Howlett@Oracle.com>
As there is no longer a vmacache, find_vma() is more expensive and so
avoid doing them
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
---
mm/mmap.c | 115 ++++++++++++++++++++++++++++--------------------------
1 file changed, 59 insertions(+), 56 deletions(-)
diff --git a/mm/mmap.c b/mm/mmap.c
index cc9d0c524d575..af426972c9dd2 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2585,44 +2585,6 @@ static void unmap_region(struct mm_struct *mm,
tlb_finish_mmu(&tlb, start, end);
}
-/*
- * Create a list of vma's touched by the unmap, removing them from the mm's
- * vma list as we go..
- */
-static bool
-detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
- struct vm_area_struct *prev, unsigned long end)
-{
- struct vm_area_struct **insertion_point;
- struct vm_area_struct *tail_vma = NULL;
-
- insertion_point = (prev ? &prev->vm_next : &mm->mmap);
- vma->vm_prev = NULL;
- vma_mt_szero(mm, vma->vm_start, end);
- do {
- mm->map_count--;
- tail_vma = vma;
- vma = vma->vm_next;
- } while (vma && vma->vm_start < end);
- *insertion_point = vma;
- if (vma)
- vma->vm_prev = prev;
- else
- mm->highest_vm_end = prev ? vm_end_gap(prev) : 0;
- tail_vma->vm_next = NULL;
-
- /*
- * Do not downgrade mmap_lock if we are next to VM_GROWSDOWN or
- * VM_GROWSUP VMA. Such VMAs can change their size under
- * down_read(mmap_lock) and collide with the VMA we are about to unmap.
- */
- if (vma && (vma->vm_flags & VM_GROWSDOWN))
- return false;
- if (prev && (prev->vm_flags & VM_GROWSUP))
- return false;
- return true;
-}
-
/*
* __split_vma() bypasses sysctl_max_map_count checking. We use this where it
* has already been checked or doesn't make sense to fail.
@@ -2702,12 +2664,16 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
return __split_vma(mm, vma, addr, new_below);
}
-static inline void unlock_range(struct vm_area_struct *start, unsigned long limit)
+static inline int unlock_range(struct vm_area_struct *start,
+ struct vm_area_struct **tail, unsigned long limit)
{
struct mm_struct *mm = start->vm_mm;
struct vm_area_struct *tmp = start;
+ int count = 0;
while (tmp && tmp->vm_start < limit) {
+ *tail = tmp;
+ count++;
if (tmp->vm_flags & VM_LOCKED) {
mm->locked_vm -= vma_pages(tmp);
munlock_vma_pages_all(tmp);
@@ -2715,6 +2681,8 @@ static inline void unlock_range(struct vm_area_struct *start, unsigned long limi
tmp = tmp->vm_next;
}
+
+ return count;
}
/* Munmap is split into 2 main parts -- this part which finds
* what needs doing, and the areas themselves, which do the
@@ -2726,24 +2694,24 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
{
unsigned long end;
struct vm_area_struct *vma, *prev, *last;
+ MA_STATE(mas, &mm->mm_mt, start, start);
if ((offset_in_page(start)) || start > TASK_SIZE || len > TASK_SIZE-start)
return -EINVAL;
- len = PAGE_ALIGN(len);
- end = start + len;
- if (len == 0)
+ end = start + PAGE_ALIGN(len);
+ if (end == start)
return -EINVAL;
/* arch_unmap() might do unmaps itself. */
arch_unmap(mm, start, end);
/* Find the first overlapping VMA */
- vma = find_vma_intersection(mm, start, end);
+ vma = mas_find(&mas, end - 1);
if (!vma)
return 0;
- prev = vma->vm_prev;
+ mas.last = end - 1;
/* we have start < vma->vm_end */
/*
@@ -2767,16 +2735,27 @@ int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len,
if (error)
return error;
prev = vma;
+ vma = vma_next(mm, prev);
+ mas.index = start;
+ mas_reset(&mas);
+ } 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);
+ mas_reset(&mas);
}
- vma = vma_next(mm, prev);
+
if (unlikely(uf)) {
/*
@@ -2789,22 +2768,46 @@ 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;
}
/*
- * unlock any mlock()ed ranges before detaching vmas
+ * unlock any mlock()ed ranges before detaching vmas, count the number
+ * of VMAs to be dropped, and return the tail entry of the affected
+ * area.
*/
- if (mm->locked_vm)
- unlock_range(vma, end);
+ mm->map_count -= unlock_range(vma, &last, end);
+ /* Drop removed area from the tree */
+ mas_store_gfp(&mas, NULL, GFP_KERNEL);
+
+ /* Detach vmas from the MM linked list */
+ vma->vm_prev = NULL;
+ if (prev)
+ prev->vm_next = last->vm_next;
+ else
+ mm->mmap = last->vm_next;
- /* Detach vmas from the MM linked list and remove from the mm tree*/
- if (!detach_vmas_to_be_unmapped(mm, vma, prev, end))
- downgrade = false;
+ if (last->vm_next) {
+ last->vm_next->vm_prev = prev;
+ last->vm_next = NULL;
+ } else
+ mm->highest_vm_end = prev ? vm_end_gap(prev) : 0;
- if (downgrade)
- mmap_write_downgrade(mm);
+ /*
+ * Do not downgrade mmap_lock if we are next to VM_GROWSDOWN or
+ * VM_GROWSUP VMA. Such VMAs can change their size under
+ * down_read(mmap_lock) and collide with the VMA we are about to unmap.
+ */
+ if (downgrade) {
+ if (last && (last->vm_flags & VM_GROWSDOWN))
+ downgrade = false;
+ else if (prev && (prev->vm_flags & VM_GROWSUP))
+ downgrade = false;
+ else
+ mmap_write_downgrade(mm);
+ }
unmap_region(mm, vma, prev, start, end);
@@ -3227,7 +3230,7 @@ void exit_mmap(struct mm_struct *mm)
}
if (mm->locked_vm)
- unlock_range(mm->mmap, ULONG_MAX);
+ unlock_range(mm->mmap, &vma, ULONG_MAX);
arch_exit_mmap(mm);
--
2.28.0
next prev parent reply other threads:[~2021-01-12 16:14 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-12 16:11 [PATCH v2 00/70] RFC mm: Introducing the Maple Tree Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 01/70] radix tree test suite: Enhancements for " Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 02/70] radix tree test suite: Add support for fallthrough attribute Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 03/70] radix tree test suite: Add support for kmem_cache_free_bulk Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 04/70] radix tree test suite: Add keme_cache_alloc_bulk() support Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 05/70] Maple Tree: Add new data structure Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 06/70] mm: Start tracking VMAs with maple tree Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 07/70] mm/mmap: Introduce unlock_range() for code cleanup Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 08/70] mm/mmap: Change find_vma() to use the maple tree Liam R. Howlett
2021-01-12 21:01 ` Randy Dunlap
2021-01-12 16:11 ` [PATCH v2 09/70] mm/mmap: Change find_vma_prev() to use " Liam R. Howlett
2021-01-12 21:03 ` Randy Dunlap
2021-01-12 16:11 ` [PATCH v2 10/70] mm/mmap: Change unmapped_area and unmapped_area_topdown " Liam R. Howlett
2021-01-12 21:05 ` Randy Dunlap
2021-01-12 16:11 ` [PATCH v2 11/70] kernel/fork: Convert dup_mmap " Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 12/70] mm: Remove rb tree Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 13/70] mm/gup: Add mm_populate_vma() for use when the vma is known Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 14/70] mm/mmap: Change do_brk_flags() to expand existing VMA and add do_brk_munmap() Liam R. Howlett
2021-01-12 21:15 ` Randy Dunlap
2021-01-13 14:20 ` Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 15/70] mm/mmap: Change vm_brk_flags() to use mm_populate_vma() Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 16/70] mm: Move find_vma_intersection to mmap.c and change implementation to maple tree Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 17/70] mm/mmap: Change mmap_region to use maple tree state Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 18/70] mm/mmap: Drop munmap_vma_range() Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 19/70] mm: Remove vmacache Liam R. Howlett
2021-01-12 16:11 ` Liam R. Howlett [this message]
2021-01-12 16:11 ` [PATCH v2 21/70] mm/mmap: Move mmap_region() below do_munmap() Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 22/70] mm/mmap: Add do_mas_munmap() and wraper for __do_munmap() Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 23/70] mmap: Use find_vma_intersection in do_mmap() for overlap Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 24/70] mmap: Remove __do_munmap() in favour of do_mas_munmap() Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 25/70] mm/mmap: Change do_brk_munmap() to use do_mas_align_munmap() Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 26/70] mmap: make remove_vma_list() inline Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 27/70] mm: Introduce vma_next() and vma_prev() Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 28/70] arch/arm64: Remove mmap linked list from vdso Liam R. Howlett
2021-01-12 16:11 ` [PATCH v2 29/70] arch/parsic: Remove mmap linked list from kernel/cache Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 30/70] arch/powerpc: Remove mmap linked list from mm/book2s32/tlb Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 31/70] arch/powerpc: Remove mmap linked list from mm/book2s32/subpage_prot Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 32/70] arch/powerpc: Optimize cell spu task sync Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 33/70] arch/s390: Use maple tree iterators instead of linked list Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 34/70] arch/um: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 35/70] arch/x86: Use maple tree iterators for vdso/vma Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 36/70] arch/xtensa: Use maple tree iterators for unmapped area Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 37/70] drivers/misc/cxl: Use maple tree iterators for cxl_prefault_vma() Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 38/70] drivers/oprofile: Lookup address in tree instead of linked list Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 39/70] drivers/tee/optee: Use maple tree iterators for __check_mem_type() Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 40/70] fs/binfmt_elf: Use maple tree iterators for fill_files_note() Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 41/70] fs/coredump: Use maple tree iterators in place of linked list Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 42/70] fs/exec: Use vma_next() instead " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 43/70] fs/proc/base: Use maple tree iterators in place " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 44/70] fs/proc/task_mmu: Stop using linked list and highest_vm_end Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 45/70] fs/userfaultfd: Stop using vma linked list Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 46/70] ipc/shm: Stop using the " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 47/70] kernel/acct: Use maple tree iterators instead of " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 48/70] kernel/events/core: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 49/70] kernel/events/uprobes: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 50/70] kernel/sched/fair: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 51/70] kernel/sys: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 52/70] mm/gup: Use maple tree navigation " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 53/70] mm/huge_memory: Use vma_next() instead of vma " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 54/70] mm/khugepaged: Use maple tree iterators " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 55/70] mm/ksm: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 56/70] mm/madvise: Use vma_next " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 57/70] mm/memcontrol: Stop using mm->highest_vm_end Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 58/70] mm/mempolicy: Use maple tree iterators instead of vma linked list Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 59/70] mm/mlock: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 60/70] mm/mprotect: Use maple tree navigation " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 61/70] mm/mremap: Use vma_next() " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 62/70] mm/msync: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 63/70] mm/nommu: Use maple tree iterators " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 64/70] mm/oom_kill: " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 65/70] mm/pagewalk: Use vma_next() " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 66/70] mm/swapfile: Use maple tree iterator " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 67/70] mm/nommu: Stop inserting into the " Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 68/70] mm/util: Remove __vma_link_list() and __vma_unlink_list() Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 69/70] mm: Remove vma linked list Liam R. Howlett
2021-01-12 16:12 ` [PATCH v2 70/70] mm/mmap: Convert __insert_vm_struct to use mas, convert vma_link to use vma_mas_link() Liam R. Howlett
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210112161240.2024684-21-Liam.Howlett@Oracle.com \
--to=liam.howlett@oracle.com \
--cc=akpm@google.com \
--cc=axelrasmussen@google.com \
--cc=dave@stgolabs.net \
--cc=jglisse@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=maple-tree@lists.infradead.org \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=riel@surriel.com \
--cc=rientjes@google.com \
--cc=songliubraving@fb.com \
--cc=surenb@google.com \
--cc=vbabka@suse.cz \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox