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:
parent
998ec9f54d
commit
57b3f8a5ab
1 changed files with 14 additions and 1 deletions
15
mm/mmap.c
15
mm/mmap.c
|
|
@ -618,6 +618,12 @@ nomem:
|
|||
* The following helper function should be used when such adjustments
|
||||
* are necessary. The "insert" vma (if any) is to be inserted
|
||||
* 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,
|
||||
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);
|
||||
struct vm_area_struct *exporter = NULL, *importer = NULL;
|
||||
|
||||
vma_start_write(vma);
|
||||
if (next)
|
||||
vma_start_write(next);
|
||||
|
||||
if (next && !insert) {
|
||||
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 + (end > next->vm_end);
|
||||
if (remove_next == 2)
|
||||
if (remove_next == 2) {
|
||||
next_next = find_vma(mm, next->vm_end);
|
||||
if (next_next)
|
||||
vma_start_write(next_next);
|
||||
}
|
||||
|
||||
VM_WARN_ON(remove_next == 2 &&
|
||||
end != next_next->vm_end);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue