]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm/khugepaged: write-lock VMA while collapsing a huge page
authorSuren Baghdasaryan <surenb@google.com>
Sat, 11 Jun 2022 04:32:23 +0000 (21:32 -0700)
committerSuren Baghdasaryan <surenb@google.com>
Wed, 23 Nov 2022 02:09:45 +0000 (02:09 +0000)
Protect VMA from concurrent page fault handler while collapsing a huge
page. Page fault handler needs a stable PMD to use PTL and relies on
per-VMA lock to prevent concurrent PMD changes. pmdp_collapse_flush(),
set_huge_pmd() and collapse_and_free_pmd() can modify a PMD, which will
not be detected by a page fault handler without proper locking.

Signed-off-by: Suren Baghdasaryan <surenb@google.com>
mm/khugepaged.c

index c7e0385556130bd0b3e0a5fac0e12a2a6ac55187..65265163870dbe1817f58a986362367629443751 100644 (file)
@@ -1038,6 +1038,7 @@ static int collapse_huge_page(struct mm_struct *mm, unsigned long address,
        if (result != SCAN_SUCCEED)
                goto out_up_write;
 
+       vma_write_lock(vma);
        anon_vma_lock_write(vma->anon_vma);
 
        mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, NULL, mm,
@@ -1479,6 +1480,9 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
                goto drop_hpage;
        }
 
+       /* Lock the vma before taking page table locks */
+       vma_write_lock(vma);
+
        start_pte = pte_offset_map_lock(mm, pmd, haddr, &ptl);
        result = SCAN_FAIL;
 
@@ -1648,6 +1652,7 @@ static int retract_page_tables(struct address_space *mapping, pgoff_t pgoff,
                                result = SCAN_PTE_UFFD_WP;
                                goto unlock_next;
                        }
+                       vma_write_lock(vma);
                        collapse_and_free_pmd(mm, vma, addr, pmd);
                        if (!cc->is_khugepaged && is_target)
                                result = set_huge_pmd(vma, addr, pmd, hpage);