summaryrefslogtreecommitdiff
path: root/mm/mmap.c
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2023-03-09 12:12:49 +0100
committerAndrew Morton <akpm@linux-foundation.org>2023-04-05 19:42:48 -0700
commit50dac01113ad7ecac86384998103d6a98020d0c4 (patch)
tree62adaffadd5c912632f71c52bc6904c542c1d765 /mm/mmap.c
parent0289184476c845968ad6ac9083c96cc0f75ca505 (diff)
mm/mmap/vma_merge: use only primary pointers for preparing merge
Patch series "cleanup vma_merge() and improve mergeability tests". My initial goal here was to try making the check for vm_ops->close in is_mergeable_vma() only be applied for vma's that would be truly removed as part of the merge (see Patch 9). This would then allow reverting the quick fix d014cd7c1c35 ("mm, mremap: fix mremap() expanding for vma's with vm_ops->close()"). This was successful enough to allow the revert (Patch 10). Checks using can_vma_merge_before() are still pessimistic about possible vma removal, and making them precise would probably complicate the vma_merge() code too much. Liam's 6.3-rc1 simplification of vma_merge() and removal of __vma_adjust() was very much helpful in understanding the vma_merge() implementation and especially when vma removals can happen, which is now very obvious. While studing the code, I've found ways to make it hopefully even more easy to follow, so that's the patches 1-8. That made me also notice a bug that's now already fixed in 6.3-rc1. This patch (of 10): In the merging preparation part of vma_merge(), some vma pointer variables are assigned for later execution of the merge, but also read from in the block itself. The code is easier follow and check against the cases diagram in the comment if the code reads only from the "primary" vma variables prev, mid, next instead. No functional change. Link: https://lkml.kernel.org/r/20230309111258.24079-1-vbabka@suse.cz Link: https://lkml.kernel.org/r/20230309111258.24079-2-vbabka@suse.cz Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>] Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Suren Baghdasaryan <surenb@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm/mmap.c')
-rw-r--r--mm/mmap.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index ad499f7b767f..bbb8d1226281 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -950,16 +950,16 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
is_mergeable_anon_vma(prev->anon_vma, next->anon_vma, NULL)) {
remove = mid; /* case 1 */
vma_end = next->vm_end;
- err = dup_anon_vma(res, remove);
+ err = dup_anon_vma(prev, mid);
if (mid != next) { /* case 6 */
remove2 = next;
- if (!remove->anon_vma)
- err = dup_anon_vma(res, remove2);
+ if (!mid->anon_vma)
+ err = dup_anon_vma(prev, next);
}
} else if (merge_prev) {
err = 0; /* case 2 */
if (mid && end > mid->vm_start) {
- err = dup_anon_vma(res, mid);
+ err = dup_anon_vma(prev, mid);
if (end == mid->vm_end) { /* case 7 */
remove = mid;
} else { /* case 5 */
@@ -972,8 +972,8 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
if (prev && addr < prev->vm_end) { /* case 4 */
vma_end = addr;
adjust = mid;
- adj_next = -(vma->vm_end - addr);
- err = dup_anon_vma(adjust, prev);
+ adj_next = -(prev->vm_end - addr);
+ err = dup_anon_vma(mid, prev);
} else {
vma = next; /* case 3 */
vma_start = addr;
@@ -982,7 +982,7 @@ struct vm_area_struct *vma_merge(struct vma_iterator *vmi, struct mm_struct *mm,
err = 0;
if (mid != next) { /* case 8 */
remove = mid;
- err = dup_anon_vma(res, remove);
+ err = dup_anon_vma(next, mid);
}
}
}