From: Jérôme Glisse <jgli...@redhat.com>

Commit c7ab0d2fdc840266b39db94538f74207ec2afbf6 silently modified
semantic of mmu_notifier_invalidate_page() this patch restore it
to its previous semantic ie allowing to sleep inside invalidate_page()
callback.

Signed-off-by: Jérôme Glisse <jgli...@redhat.com>
Cc: Kirill A. Shutemov <kirill.shute...@linux.intel.com>
---
 mm/rmap.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/mm/rmap.c b/mm/rmap.c
index 92070cfd63e9..fc1e2ab194c0 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -888,6 +888,8 @@ static bool page_mkclean_one(struct page *page, struct 
vm_area_struct *vma,
                .address = address,
                .flags = PVMW_SYNC,
        };
+       unsigned long start = address, end = address;
+       bool invalidate = false;
        int *cleaned = arg;
 
        while (page_vma_mapped_walk(&pvmw)) {
@@ -927,11 +929,17 @@ static bool page_mkclean_one(struct page *page, struct 
vm_area_struct *vma,
                }
 
                if (ret) {
-                       mmu_notifier_invalidate_page(vma->vm_mm, address);
+                       invalidate = true;
+                       end = address;
                        (*cleaned)++;
                }
        }
 
+       if (invalidate) {
+               for (address = start; address <= end; address += PAGE_SIZE)
+                       mmu_notifier_invalidate_page(vma->vm_mm, address);
+       }
+
        return true;
 }
 
@@ -1324,7 +1332,8 @@ static bool try_to_unmap_one(struct page *page, struct 
vm_area_struct *vma,
        };
        pte_t pteval;
        struct page *subpage;
-       bool ret = true;
+       bool ret = true, invalidate = false;
+       unsigned long start = address, end = address;
        enum ttu_flags flags = (enum ttu_flags)arg;
 
        /* munlock has nothing to gain from examining un-locked vmas */
@@ -1528,8 +1537,15 @@ static bool try_to_unmap_one(struct page *page, struct 
vm_area_struct *vma,
 discard:
                page_remove_rmap(subpage, PageHuge(page));
                put_page(page);
-               mmu_notifier_invalidate_page(mm, address);
+               end = address;
+               invalidate = true;
        }
+
+       if (invalidate) {
+               for (address = start; address <= end; address += PAGE_SIZE)
+                       mmu_notifier_invalidate_page(mm, address);
+       }
+
        return ret;
 }
 
-- 
2.13.4

Reply via email to