From b5e6a135573c779a59c8ee52a2b1c8f9dfd54520 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 15 Oct 2008 22:01:11 -0700 Subject: [PATCH] --- yaml --- r: 114687 b: refs/heads/master c: b4d1d99fdd8b98fb03dfd6ef9b0ece220de38640 h: refs/heads/master i: 114685: f260492c9569a0ba66420fcb4db6074d849933ad 114683: 1b8e6b599055e25138a35e75962dcdfc0008b44a 114679: 9991b6b89c625c65573903f4d2dca98f725f01f9 114671: bb1f8ee14eaa8c5493481c9ac31a2f50d36187b5 114655: 34d2d6dca892b1d7f056c8c781d5dff1a51c819b 114623: f572d57247952abdd8af430a7a435bdcc35dae01 114559: f2bec94fbb81fa5e9e86144bae0f12f1ca19c2b9 114431: 7ac63b8fd742472564d441591752034fb6f45a92 114175: d406eedace545c76c0fb1c871131a0fc82a24f39 113663: e6a0e50f2abe5324c8482d471a7fd66bbdab35a8 112639: 6447e5ac2a59007a7babd51b1271b0a4927ecb29 110591: 6c83fc64e76a2e89998466e802b1aed3dabc2703 106495: 875b556c2a6c4cb2319b38607585bd7a1a584c3a 98303: 8d3fd52306c01a77327e5a8547cc363fa60bb45f v: v3 --- [refs] | 2 +- trunk/mm/hugetlb.c | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 466ea696b0bd..611dcc5bd9d2 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: db99100d2ed40dd9736fcb1adb3657a98f9bcfd9 +refs/heads/master: b4d1d99fdd8b98fb03dfd6ef9b0ece220de38640 diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 67a71191136e..38633864a93e 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -2008,7 +2008,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, entry = huge_ptep_get(ptep); if (huge_pte_none(entry)) { ret = hugetlb_no_page(mm, vma, address, ptep, write_access); - goto out_unlock; + goto out_mutex; } ret = 0; @@ -2024,7 +2024,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, if (write_access && !pte_write(entry)) { if (vma_needs_reservation(h, vma, address) < 0) { ret = VM_FAULT_OOM; - goto out_unlock; + goto out_mutex; } if (!(vma->vm_flags & VM_SHARED)) @@ -2034,10 +2034,23 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, spin_lock(&mm->page_table_lock); /* Check for a racing update before calling hugetlb_cow */ - if (likely(pte_same(entry, huge_ptep_get(ptep)))) - if (write_access && !pte_write(entry)) + if (unlikely(!pte_same(entry, huge_ptep_get(ptep)))) + goto out_page_table_lock; + + + if (write_access) { + if (!pte_write(entry)) { ret = hugetlb_cow(mm, vma, address, ptep, entry, pagecache_page); + goto out_page_table_lock; + } + entry = pte_mkdirty(entry); + } + entry = pte_mkyoung(entry); + if (huge_ptep_set_access_flags(vma, address, ptep, entry, write_access)) + update_mmu_cache(vma, address, entry); + +out_page_table_lock: spin_unlock(&mm->page_table_lock); if (pagecache_page) { @@ -2045,7 +2058,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, put_page(pagecache_page); } -out_unlock: +out_mutex: mutex_unlock(&hugetlb_instantiation_mutex); return ret;