mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
FROMLIST: mm/mmap: write-lock VMAs in vma_adjust
vma_adjust modifies a VMA and possibly its neighbors. Write-lock them before making the modifications. Signed-off-by: Suren Baghdasaryan <surenb@google.com> Link: https://lore.kernel.org/all/20230109205336.3665937-21-surenb@google.com/ [surenb: using older v1 of patchset due to __vma_adjust() being removed in 6.2-rc4] [surenb: minor fixes in next_next locking inside __vma_adjust] Bug: 161210518 Change-Id: I9ab2f88c82a7071fe2f1a14c51a2e6f1b6196681 Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
committed by
Carlos Llamas
parent
998ec9f54d
commit
57b3f8a5ab
15
mm/mmap.c
15
mm/mmap.c
@@ -618,6 +618,12 @@ nomem:
|
|||||||
* The following helper function should be used when such adjustments
|
* The following helper function should be used when such adjustments
|
||||||
* are necessary. The "insert" vma (if any) is to be inserted
|
* are necessary. The "insert" vma (if any) is to be inserted
|
||||||
* before we drop the necessary locks.
|
* before we drop the necessary locks.
|
||||||
|
* 'expand' vma is always locked before it's passed to __vma_adjust()
|
||||||
|
* from vma_merge() because vma should not change from the moment
|
||||||
|
* can_vma_merge_{before|after} decision is made.
|
||||||
|
* 'insert' vma is used only by __split_vma() and it's always a brand
|
||||||
|
* new vma which is not yet added into mm's vma tree, therefore no need
|
||||||
|
* to lock it.
|
||||||
*/
|
*/
|
||||||
int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
|
int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
|
||||||
unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert,
|
unsigned long end, pgoff_t pgoff, struct vm_area_struct *insert,
|
||||||
@@ -637,6 +643,10 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
|
|||||||
MA_STATE(mas, &mm->mm_mt, start, end - 1);
|
MA_STATE(mas, &mm->mm_mt, start, end - 1);
|
||||||
struct vm_area_struct *exporter = NULL, *importer = NULL;
|
struct vm_area_struct *exporter = NULL, *importer = NULL;
|
||||||
|
|
||||||
|
vma_start_write(vma);
|
||||||
|
if (next)
|
||||||
|
vma_start_write(next);
|
||||||
|
|
||||||
if (next && !insert) {
|
if (next && !insert) {
|
||||||
if (end >= next->vm_end) {
|
if (end >= next->vm_end) {
|
||||||
/*
|
/*
|
||||||
@@ -666,8 +676,11 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
|
|||||||
* remove_next == 1 is case 1 or 7.
|
* remove_next == 1 is case 1 or 7.
|
||||||
*/
|
*/
|
||||||
remove_next = 1 + (end > next->vm_end);
|
remove_next = 1 + (end > next->vm_end);
|
||||||
if (remove_next == 2)
|
if (remove_next == 2) {
|
||||||
next_next = find_vma(mm, next->vm_end);
|
next_next = find_vma(mm, next->vm_end);
|
||||||
|
if (next_next)
|
||||||
|
vma_start_write(next_next);
|
||||||
|
}
|
||||||
|
|
||||||
VM_WARN_ON(remove_next == 2 &&
|
VM_WARN_ON(remove_next == 2 &&
|
||||||
end != next_next->vm_end);
|
end != next_next->vm_end);
|
||||||
|
|||||||
Reference in New Issue
Block a user