diff --git a/[refs] b/[refs] index 071bf4b652e1..e788e00cde03 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2e9b367c2273ed21c9852a04d90944d472c4f3e6 +refs/heads/master: 1a44e149084d772a1bcf4cdbdde8a013a8a1cfde diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index d68421dd64ef..0f60baf6f69b 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -1980,9 +1980,10 @@ static inline int handle_pte_fault(struct mm_struct *mm, pte_t *pte, pmd_t *pmd, int write_access) { pte_t entry; + pte_t old_entry; spinlock_t *ptl; - entry = *pte; + old_entry = entry = *pte; if (!pte_present(entry)) { if (pte_none(entry)) { if (!vma->vm_ops || !vma->vm_ops->nopage) @@ -2009,9 +2010,20 @@ static inline int handle_pte_fault(struct mm_struct *mm, entry = pte_mkdirty(entry); } entry = pte_mkyoung(entry); - ptep_set_access_flags(vma, address, pte, entry, write_access); - update_mmu_cache(vma, address, entry); - lazy_mmu_prot_update(entry); + if (!pte_same(old_entry, entry)) { + ptep_set_access_flags(vma, address, pte, entry, write_access); + update_mmu_cache(vma, address, entry); + lazy_mmu_prot_update(entry); + } else { + /* + * This is needed only for protection faults but the arch code + * is not yet telling us if this is a protection fault or not. + * This still avoids useless tlb flushes for .text page faults + * with threads. + */ + if (write_access) + flush_tlb_page(vma, address); + } unlock: pte_unmap_unlock(pte, ptl); return VM_FAULT_MINOR;