From: "Liam R. Howlett" <Liam.Howlett@oracle.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Suren Baghdasaryan <surenb@google.com>,
Lorenzo Stoakes <lorenzo.stoakes@oracle.com>,
Matthew Wilcox <willy@infradead.org>,
Vlastimil Babka <vbabka@suse.cz>,
sidhartha.kumar@oracle.com, Bert Karwatzki <spasswolf@web.de>,
Jiri Olsa <olsajiri@gmail.com>, Kees Cook <kees@kernel.org>,
"Paul E . McKenney" <paulmck@kernel.org>,
"Liam R. Howlett" <Liam.Howlett@Oracle.com>
Subject: [PATCH v7 11/21] mm/mmap: Reposition vma iterator in mmap_region()
Date: Thu, 22 Aug 2024 15:25:33 -0400 [thread overview]
Message-ID: <20240822192543.3359552-12-Liam.Howlett@oracle.com> (raw)
In-Reply-To: <20240822192543.3359552-1-Liam.Howlett@oracle.com>
From: "Liam R. Howlett" <Liam.Howlett@Oracle.com>
Instead of moving (or leaving) the vma iterator pointing at the previous
vma, leave it pointing at the insert location. Pointing the vma
iterator at the insert location allows for a cleaner walk of the vma
tree for MAP_FIXED and the no expansion cases.
The vma_prev() call in the case of merging the previous vma is
equivalent to vma_iter_prev_range(), since the vma iterator will be
pointing to the location just before the previous vma.
This change needs to export abort_munmap_vmas() from mm/vma.
Signed-off-by: Liam R. Howlett <Liam.Howlett@Oracle.com>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
---
mm/mmap.c | 38 ++++++++++++++++++++++----------------
mm/vma.c | 16 ----------------
mm/vma.h | 16 ++++++++++++++++
3 files changed, 38 insertions(+), 32 deletions(-)
diff --git a/mm/mmap.c b/mm/mmap.c
index 2b7445a002dc..9285bdf14c4f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1400,21 +1400,22 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
mas_init(&mas_detach, &mt_detach, /* addr = */ 0);
/* Prepare to unmap any existing mapping in the area */
if (vms_gather_munmap_vmas(&vms, &mas_detach))
- return -ENOMEM;
+ goto gather_failed;
/* Remove any existing mappings from the vma tree */
if (vma_iter_clear_gfp(&vmi, addr, end, GFP_KERNEL))
- return -ENOMEM;
+ goto clear_tree_failed;
/* Unmap any existing mapping in the area */
vms_complete_munmap_vmas(&vms, &mas_detach);
next = vms.next;
prev = vms.prev;
- vma_prev(&vmi);
vma = NULL;
} else {
next = vma_next(&vmi);
prev = vma_prev(&vmi);
+ if (prev)
+ vma_iter_next_range(&vmi);
}
/*
@@ -1427,11 +1428,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
vm_flags |= VM_ACCOUNT;
}
- if (vm_flags & VM_SPECIAL) {
- if (prev)
- vma_iter_next_range(&vmi);
+ if (vm_flags & VM_SPECIAL)
goto cannot_expand;
- }
/* Attempt to expand an old mapping */
/* Check next */
@@ -1452,19 +1450,21 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
merge_start = prev->vm_start;
vma = prev;
vm_pgoff = prev->vm_pgoff;
- } else if (prev) {
- vma_iter_next_range(&vmi);
+ vma_prev(&vmi); /* Equivalent to going to the previous range */
}
- /* Actually expand, if possible */
- if (vma &&
- !vma_expand(&vmi, vma, merge_start, merge_end, vm_pgoff, next)) {
- khugepaged_enter_vma(vma, vm_flags);
- goto expanded;
+ if (vma) {
+ /* Actually expand, if possible */
+ if (!vma_expand(&vmi, vma, merge_start, merge_end, vm_pgoff, next)) {
+ khugepaged_enter_vma(vma, vm_flags);
+ goto expanded;
+ }
+
+ /* If the expand fails, then reposition the vma iterator */
+ if (unlikely(vma == prev))
+ vma_iter_set(&vmi, addr);
}
- if (vma == prev)
- vma_iter_set(&vmi, addr);
cannot_expand:
/*
@@ -1625,6 +1625,12 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
vm_unacct_memory(charged);
validate_mm(mm);
return error;
+
+clear_tree_failed:
+ abort_munmap_vmas(&mas_detach);
+gather_failed:
+ validate_mm(mm);
+ return -ENOMEM;
}
static int __vm_munmap(unsigned long start, size_t len, bool unlock)
diff --git a/mm/vma.c b/mm/vma.c
index 6b30f9748187..9de41e1bf3b2 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -646,22 +646,6 @@ void vma_complete(struct vma_prepare *vp,
uprobe_mmap(vp->insert);
}
-/*
- * abort_munmap_vmas - Undo any munmap work and free resources
- *
- * Reattach any detached vmas and free up the maple tree used to track the vmas.
- */
-static inline void abort_munmap_vmas(struct ma_state *mas_detach)
-{
- struct vm_area_struct *vma;
-
- mas_set(mas_detach, 0);
- mas_for_each(mas_detach, vma, ULONG_MAX)
- vma_mark_detached(vma, false);
-
- __mt_destroy(mas_detach->tree);
-}
-
/*
* vms_complete_munmap_vmas() - Finish the munmap() operation
* @vms: The vma munmap struct
diff --git a/mm/vma.h b/mm/vma.h
index 0e214bbf443e..c85fc7c888a8 100644
--- a/mm/vma.h
+++ b/mm/vma.h
@@ -116,6 +116,22 @@ int vms_gather_munmap_vmas(struct vma_munmap_struct *vms,
void vms_complete_munmap_vmas(struct vma_munmap_struct *vms,
struct ma_state *mas_detach);
+/*
+ * abort_munmap_vmas - Undo any munmap work and free resources
+ *
+ * Reattach any detached vmas and free up the maple tree used to track the vmas.
+ */
+static inline void abort_munmap_vmas(struct ma_state *mas_detach)
+{
+ struct vm_area_struct *vma;
+
+ mas_set(mas_detach, 0);
+ mas_for_each(mas_detach, vma, ULONG_MAX)
+ vma_mark_detached(vma, false);
+
+ __mt_destroy(mas_detach->tree);
+}
+
int
do_vmi_align_munmap(struct vma_iterator *vmi, struct vm_area_struct *vma,
struct mm_struct *mm, unsigned long start,
--
2.43.0
next prev parent reply other threads:[~2024-08-22 19:27 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-22 19:25 [PATCH v7 00/21] Avoid MAP_FIXED gap exposure Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 01/21] mm/vma: Correctly position vma_iterator in __split_vma() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 02/21] mm/vma: Introduce abort_munmap_vmas() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 03/21] mm/vma: Introduce vmi_complete_munmap_vmas() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 04/21] mm/vma: Extract the gathering of vmas from do_vmi_align_munmap() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 05/21] mm/vma: Introduce vma_munmap_struct for use in munmap operations Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 06/21] mm/vma: Change munmap to use vma_munmap_struct() for accounting and surrounding vmas Liam R. Howlett
2024-08-23 8:43 ` Bert Karwatzki
2024-08-23 9:55 ` Lorenzo Stoakes
2024-08-23 10:42 ` Bert Karwatzki
2024-08-23 11:39 ` Lorenzo Stoakes
2024-08-23 11:37 ` Lorenzo Stoakes
2024-08-23 13:30 ` [PATCH] mm/vma: fix bookkeeping checks Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 07/21] mm/vma: Extract validate_mm() from vma_complete() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 08/21] mm/vma: Inline munmap operation in mmap_region() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 09/21] mm/vma: Expand mmap_region() munmap call Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 10/21] mm/vma: Support vma == NULL in init_vma_munmap() Liam R. Howlett
2024-08-22 19:25 ` Liam R. Howlett [this message]
2024-08-22 19:25 ` [PATCH v7 12/21] mm/vma: Track start and end for munmap in vma_munmap_struct Liam R. Howlett
2024-08-26 14:01 ` Geert Uytterhoeven
2024-08-26 14:12 ` Lorenzo Stoakes
2024-08-22 19:25 ` [PATCH v7 13/21] mm: Clean up unmap_region() argument list Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 14/21] mm/mmap: Avoid zeroing vma tree in mmap_region() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 15/21] mm: Change failure of MAP_FIXED to restoring the gap on failure Liam R. Howlett
2024-08-27 17:15 ` [PATCH] mm/vma: Fix null pointer dereference in vms_abort_munmap_vmas() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 16/21] mm/mmap: Use PHYS_PFN in mmap_region() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 17/21] mm/mmap: Use vms accounted pages " Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 18/21] ipc/shm, mm: Drop do_vma_munmap() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 19/21] mm: Move may_expand_vm() check in mmap_region() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 20/21] mm/vma: Drop incorrect comment from vms_gather_munmap_vmas() Liam R. Howlett
2024-08-22 19:25 ` [PATCH v7 21/21] mm/vma.h: Optimise vma_munmap_struct Liam R. Howlett
2024-08-22 19:41 ` Lorenzo Stoakes
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=20240822192543.3359552-12-Liam.Howlett@oracle.com \
--to=liam.howlett@oracle.com \
--cc=akpm@linux-foundation.org \
--cc=kees@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lorenzo.stoakes@oracle.com \
--cc=olsajiri@gmail.com \
--cc=paulmck@kernel.org \
--cc=sidhartha.kumar@oracle.com \
--cc=spasswolf@web.de \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.