| From 6c57d0d0576a8c2778f4659a0b852271cd0e029a Mon Sep 17 00:00:00 2001 |
| From: Yongqin Liu <yongqin.liu@linaro.org> |
| Date: Fri, 28 Jul 2023 16:14:55 +0800 |
| Subject: [PATCH 6/7] Revert "mm/mremap: retry if either pte_offset_map_*lock() |
| fails" |
| |
| This reverts commit a5be621ee2925b6ee2db455c45c2af2d8a195b0c. |
| --- |
| mm/huge_memory.c | 5 ++--- |
| mm/mremap.c | 28 ++++++++-------------------- |
| 2 files changed, 10 insertions(+), 23 deletions(-) |
| |
| diff --git a/mm/huge_memory.c b/mm/huge_memory.c |
| index a37e86c09c5e..b36e62a4fb75 100644 |
| --- a/mm/huge_memory.c |
| +++ b/mm/huge_memory.c |
| @@ -1760,10 +1760,9 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr, |
| |
| /* |
| * The destination pmd shouldn't be established, free_pgtables() |
| - * should have released it; but move_page_tables() might have already |
| - * inserted a page table, if racing against shmem/file collapse. |
| + * should have release it. |
| */ |
| - if (!pmd_none(*new_pmd)) { |
| + if (WARN_ON(!pmd_none(*new_pmd))) { |
| VM_BUG_ON(pmd_trans_huge(*new_pmd)); |
| return false; |
| } |
| diff --git a/mm/mremap.c b/mm/mremap.c |
| index 1be0b7ab2590..75a3db3913e4 100644 |
| --- a/mm/mremap.c |
| +++ b/mm/mremap.c |
| @@ -133,7 +133,7 @@ static pte_t move_soft_dirty_pte(pte_t pte) |
| return pte; |
| } |
| |
| -static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, |
| +static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, |
| unsigned long old_addr, unsigned long old_end, |
| struct vm_area_struct *new_vma, pmd_t *new_pmd, |
| unsigned long new_addr, bool need_rmap_locks) |
| @@ -143,7 +143,6 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, |
| spinlock_t *old_ptl, *new_ptl; |
| bool force_flush = false; |
| unsigned long len = old_end - old_addr; |
| - int err = 0; |
| |
| /* |
| * When need_rmap_locks is true, we take the i_mmap_rwsem and anon_vma |
| @@ -171,16 +170,8 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, |
| * pte locks because exclusive mmap_lock prevents deadlock. |
| */ |
| old_pte = pte_offset_map_lock(mm, old_pmd, old_addr, &old_ptl); |
| - if (!old_pte) { |
| - err = -EAGAIN; |
| - goto out; |
| - } |
| - new_pte = pte_offset_map_nolock(mm, new_pmd, new_addr, &new_ptl); |
| - if (!new_pte) { |
| - pte_unmap_unlock(old_pte, old_ptl); |
| - err = -EAGAIN; |
| - goto out; |
| - } |
| + new_pte = pte_offset_map(new_pmd, new_addr); |
| + new_ptl = pte_lockptr(mm, new_pmd); |
| if (new_ptl != old_ptl) |
| spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING); |
| flush_tlb_batched_pending(vma->vm_mm); |
| @@ -217,10 +208,8 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, |
| spin_unlock(new_ptl); |
| pte_unmap(new_pte - 1); |
| pte_unmap_unlock(old_pte - 1, old_ptl); |
| -out: |
| if (need_rmap_locks) |
| drop_rmap_locks(vma); |
| - return err; |
| } |
| |
| #ifndef arch_supports_page_table_move |
| @@ -548,7 +537,6 @@ unsigned long move_page_tables(struct vm_area_struct *vma, |
| new_pmd = alloc_new_pmd(vma->vm_mm, vma, new_addr); |
| if (!new_pmd) |
| break; |
| -again: |
| if (is_swap_pmd(*old_pmd) || pmd_trans_huge(*old_pmd) || |
| pmd_devmap(*old_pmd)) { |
| if (extent == HPAGE_PMD_SIZE && |
| @@ -556,6 +544,8 @@ unsigned long move_page_tables(struct vm_area_struct *vma, |
| old_pmd, new_pmd, need_rmap_locks)) |
| continue; |
| split_huge_pmd(vma, old_pmd, old_addr); |
| + if (pmd_trans_unstable(old_pmd)) |
| + continue; |
| } else if (IS_ENABLED(CONFIG_HAVE_MOVE_PMD) && |
| extent == PMD_SIZE) { |
| /* |
| @@ -566,13 +556,11 @@ unsigned long move_page_tables(struct vm_area_struct *vma, |
| old_pmd, new_pmd, true)) |
| continue; |
| } |
| - if (pmd_none(*old_pmd)) |
| - continue; |
| + |
| if (pte_alloc(new_vma->vm_mm, new_pmd)) |
| break; |
| - if (move_ptes(vma, old_pmd, old_addr, old_addr + extent, |
| - new_vma, new_pmd, new_addr, need_rmap_locks) < 0) |
| - goto again; |
| + move_ptes(vma, old_pmd, old_addr, old_addr + extent, new_vma, |
| + new_pmd, new_addr, need_rmap_locks); |
| } |
| |
| mmu_notifier_invalidate_range_end(&range); |
| -- |
| 2.25.1 |
| |