blob: 27a702b84e1faa32d63f20bc0acde56fc31722de [file] [log] [blame]
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