From ee5885b05e9754dbd4c7c9d886e77579d534d226 Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Mon, 31 Oct 2011 17:08:26 -0700 Subject: [PATCH] --- yaml --- r: 272139 b: refs/heads/master c: 7b6efc2bc4f19952b25ebf9b236e5ac43cd386c2 h: refs/heads/master i: 272137: 76ab2792716cb24d41056e6053e6aa308336c9b2 272135: b1ac3aecc151f983b0cfb2952955638eb3eea867 v: v3 --- [refs] | 2 +- trunk/mm/mremap.c | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index bdffff7c9de8..06fb460b42dc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ebed48460be5abd86d9a24fa7c66378e58109f30 +refs/heads/master: 7b6efc2bc4f19952b25ebf9b236e5ac43cd386c2 diff --git a/trunk/mm/mremap.c b/trunk/mm/mremap.c index 195e866568e0..a184f3732e1e 100644 --- a/trunk/mm/mremap.c +++ b/trunk/mm/mremap.c @@ -80,11 +80,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, struct mm_struct *mm = vma->vm_mm; pte_t *old_pte, *new_pte, pte; spinlock_t *old_ptl, *new_ptl; - unsigned long old_start; - old_start = old_addr; - mmu_notifier_invalidate_range_start(vma->vm_mm, - old_start, old_end); if (vma->vm_file) { /* * Subtle point from Rajesh Venkatasubramanian: before @@ -111,7 +107,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, new_pte++, new_addr += PAGE_SIZE) { if (pte_none(*old_pte)) continue; - pte = ptep_clear_flush(vma, old_addr, old_pte); + pte = ptep_get_and_clear(mm, old_addr, old_pte); pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); set_pte_at(mm, new_addr, new_pte, pte); } @@ -123,7 +119,6 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd, pte_unmap_unlock(old_pte - 1, old_ptl); if (mapping) mutex_unlock(&mapping->i_mmap_mutex); - mmu_notifier_invalidate_range_end(vma->vm_mm, old_start, old_end); } #define LATENCY_LIMIT (64 * PAGE_SIZE) @@ -134,10 +129,13 @@ unsigned long move_page_tables(struct vm_area_struct *vma, { unsigned long extent, next, old_end; pmd_t *old_pmd, *new_pmd; + bool need_flush = false; old_end = old_addr + len; flush_cache_range(vma, old_addr, old_end); + mmu_notifier_invalidate_range_start(vma->vm_mm, old_addr, old_end); + for (; old_addr < old_end; old_addr += extent, new_addr += extent) { cond_resched(); next = (old_addr + PMD_SIZE) & PMD_MASK; @@ -158,7 +156,12 @@ unsigned long move_page_tables(struct vm_area_struct *vma, extent = LATENCY_LIMIT; move_ptes(vma, old_pmd, old_addr, old_addr + extent, new_vma, new_pmd, new_addr); + need_flush = true; } + if (likely(need_flush)) + flush_tlb_range(vma, old_end-len, old_addr); + + mmu_notifier_invalidate_range_end(vma->vm_mm, old_end-len, old_end); return len + old_addr - old_end; /* how much done */ }