mmap: call unlink_anon_vmas() in __split_vma() in case of error
[platform/adaptation/renesas_rcar/renesas_kernel.git] / mm / hugetlb.c
index 3c275ff..cc5be78 100644 (file)
@@ -2324,9 +2324,11 @@ retry_avoidcopy:
         * and just make the page writable */
        avoidcopy = (page_mapcount(old_page) == 1);
        if (avoidcopy) {
-               if (!trylock_page(old_page))
+               if (!trylock_page(old_page)) {
                        if (PageAnon(old_page))
                                page_move_anon_rmap(old_page, vma, address);
+               } else
+                       unlock_page(old_page);
                set_huge_ptep_writable(vma, address, ptep);
                return 0;
        }
@@ -2395,6 +2397,9 @@ retry_avoidcopy:
        ptep = huge_pte_offset(mm, address & huge_page_mask(h));
        if (likely(pte_same(huge_ptep_get(ptep), pte))) {
                /* Break COW */
+               mmu_notifier_invalidate_range_start(mm,
+                       address & huge_page_mask(h),
+                       (address & huge_page_mask(h)) + huge_page_size(h));
                huge_ptep_clear_flush(vma, address, ptep);
                set_huge_pte_at(mm, address, ptep,
                                make_huge_pte(vma, new_page, 1));
@@ -2402,6 +2407,9 @@ retry_avoidcopy:
                hugepage_add_anon_rmap(new_page, vma, address);
                /* Make the old page be freed below */
                new_page = old_page;
+               mmu_notifier_invalidate_range_end(mm,
+                       address & huge_page_mask(h),
+                       (address & huge_page_mask(h)) + huge_page_size(h));
        }
        page_cache_release(new_page);
        page_cache_release(old_page);