X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=mm%2Fhugetlb.c;h=49e693b7fd0c695aeced27be87ab7ed0ae98e8d0;hb=ef009b25f4f8a77d2b32067d424d5ac757dcdc5b;hp=7acd12503f734bfcaff2c4fed244e594952962ea;hpb=979ecef5b89a8003902299566d9cdc08de34a3ee;p=platform%2Fadaptation%2Frenesas_rcar%2Frenesas_kernel.git diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 7acd125..49e693b 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -2349,6 +2349,9 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, /* * Hugetlb_cow() should be called with page lock of the original hugepage held. + * Called with hugetlb_instantiation_mutex held and pte_page locked so we + * cannot race with other handlers or page migration. + * Keep the pte_same checks anyway to make transition from the mutex easier. */ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *ptep, pte_t pte, @@ -2408,7 +2411,14 @@ retry_avoidcopy: BUG_ON(page_count(old_page) != 1); BUG_ON(huge_pte_none(pte)); spin_lock(&mm->page_table_lock); - goto retry_avoidcopy; + ptep = huge_pte_offset(mm, address & huge_page_mask(h)); + if (likely(pte_same(huge_ptep_get(ptep), pte))) + goto retry_avoidcopy; + /* + * race occurs while re-acquiring page_table_lock, and + * our job is done. + */ + return 0; } WARN_ON_ONCE(1); }