[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20240717200709.1552558-12-Liam.Howlett@oracle.com>
Date: Wed, 17 Jul 2024 16:06:59 -0400
From: "Liam R. Howlett" <Liam.Howlett@...cle.com>
To: linux-mm@...ck.org, Andrew Morton <akpm@...ux-foundation.org>
Cc: Suren Baghdasaryan <surenb@...gle.com>, Vlastimil Babka <vbabka@...e.cz>,
Lorenzo Stoakes <lstoakes@...il.com>,
Matthew Wilcox <willy@...radead.org>, sidhartha.kumar@...cle.com,
"Paul E . McKenney" <paulmck@...nel.org>,
Bert Karwatzki <spasswolf@....de>, Jiri Olsa <olsajiri@...il.com>,
linux-kernel@...r.kernel.org, Kees Cook <kees@...nel.org>,
Jeff Xu <jeffxu@...omium.org>,
"Liam R. Howlett" <Liam.Howlett@...cle.com>,
Lorenzo Stoakes <lorenzo.stoakes@...cle.com>
Subject: [PATCH v5 11/21] mm/mmap: Reposition vma iterator in mmap_region()
From: "Liam R. Howlett" <Liam.Howlett@...cle.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.
Signed-off-by: Liam R. Howlett <Liam.Howlett@...cle.com>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@...cle.com>
---
mm/mmap.c | 38 ++++++++++++++++++++++----------------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/mm/mmap.c b/mm/mmap.c
index 722bcced0499..b940de8c6df8 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2962,21 +2962,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);
}
/*
@@ -2989,11 +2990,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 */
@@ -3014,19 +3012,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:
/*
@@ -3187,6 +3187,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)
--
2.43.0
Powered by blists - more mailing lists