move_page_tables() tries to move page table by PMD or PTE.
The root reason is if it tries to move PMD, both old and new range should be
PMD aligned. But current code calculate old range and new range separately.
This leads to some redundant check and calculation.
This cleanup tries to consolidate the range check in one place to reduce some
extra range handling.
v3:
* merge patch 1 with 2 as suggested by Kirill
* add patch 4 to simplify the logic to calculate next and extent
v2:
* remove 3rd patch which doesn't work on ARM platform. Thanks report and
test from Dmitry Osipenko
Wei Yang (4):
mm/mremap: it is sure to have enough space when extent meets
requirement
mm/mremap: calculate extent in one place
mm/mremap: start addresses are properly aligned
mm/mremap: use pmd_addr_end to simplify the calculate of extent
include/linux/huge_mm.h | 2 +-
mm/huge_memory.c | 8 +-------
mm/mremap.c | 27 ++++++++++-----------------
3 files changed, 12 insertions(+), 25 deletions(-)
--
2.20.1 (Apple Git-117)
The purpose of this code is to calculate the smaller extent in old and
new range. Let's leverage pmd_addr_end() to do the calculation.
Hope this would make the code easier to read.
Signed-off-by: Wei Yang <[email protected]>
---
mm/mremap.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/mm/mremap.c b/mm/mremap.c
index f5f17d050617..76e7fdf567c3 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -237,11 +237,12 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long new_addr, unsigned long len,
bool need_rmap_locks)
{
- unsigned long extent, next, old_end;
+ unsigned long extent, old_next, new_next, old_end, new_end;
struct mmu_notifier_range range;
pmd_t *old_pmd, *new_pmd;
old_end = old_addr + len;
+ new_end = new_addr + len;
flush_cache_range(vma, old_addr, old_end);
mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma, vma->vm_mm,
@@ -250,14 +251,11 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
for (; old_addr < old_end; old_addr += extent, new_addr += extent) {
cond_resched();
- next = (old_addr + PMD_SIZE) & PMD_MASK;
- /* even if next overflowed, extent below will be ok */
- extent = next - old_addr;
- if (extent > old_end - old_addr)
- extent = old_end - old_addr;
- next = (new_addr + PMD_SIZE) & PMD_MASK;
- if (extent > next - new_addr)
- extent = next - new_addr;
+
+ old_next = pmd_addr_end(old_addr, old_end);
+ new_next = pmd_addr_end(new_addr, new_end);
+ extent = min((old_next - old_addr), (new_next - new_addr));
+
old_pmd = get_old_pmd(vma->vm_mm, old_addr);
if (!old_pmd)
continue;
--
2.20.1 (Apple Git-117)
On Wed, Jul 08, 2020 at 09:24:53AM +0800, Wei Yang wrote:
> The purpose of this code is to calculate the smaller extent in old and
> new range. Let's leverage pmd_addr_end() to do the calculation.
>
> Hope this would make the code easier to read.
>
> Signed-off-by: Wei Yang <[email protected]>
> ---
> mm/mremap.c | 16 +++++++---------
> 1 file changed, 7 insertions(+), 9 deletions(-)
>
> diff --git a/mm/mremap.c b/mm/mremap.c
> index f5f17d050617..76e7fdf567c3 100644
> --- a/mm/mremap.c
> +++ b/mm/mremap.c
> @@ -237,11 +237,12 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
> unsigned long new_addr, unsigned long len,
> bool need_rmap_locks)
> {
> - unsigned long extent, next, old_end;
> + unsigned long extent, old_next, new_next, old_end, new_end;
> struct mmu_notifier_range range;
> pmd_t *old_pmd, *new_pmd;
>
> old_end = old_addr + len;
> + new_end = new_addr + len;
> flush_cache_range(vma, old_addr, old_end);
>
> mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma, vma->vm_mm,
> @@ -250,14 +251,11 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
>
> for (; old_addr < old_end; old_addr += extent, new_addr += extent) {
> cond_resched();
> - next = (old_addr + PMD_SIZE) & PMD_MASK;
> - /* even if next overflowed, extent below will be ok */
> - extent = next - old_addr;
> - if (extent > old_end - old_addr)
> - extent = old_end - old_addr;
> - next = (new_addr + PMD_SIZE) & PMD_MASK;
> - if (extent > next - new_addr)
> - extent = next - new_addr;
> +
> + old_next = pmd_addr_end(old_addr, old_end);
> + new_next = pmd_addr_end(new_addr, new_end);
> + extent = min((old_next - old_addr), (new_next - new_addr));
Nit: redundant parentheses.
--
Kirill A. Shutemov