aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2007-06-16 13:16:12 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-16 16:16:16 -0400
commit8dab5241d06bfc9ee141ea78c56cde5070d7460d (patch)
treedd9dc3c64c17862b169f4cbe5fd4a108d960c920 /mm/memory.c
parent679ce0ace6b1a07043bc3b405a34ddccad808886 (diff)
Rework ptep_set_access_flags and fix sun4c
Some changes done a while ago to avoid pounding on ptep_set_access_flags and update_mmu_cache in some race situations break sun4c which requires update_mmu_cache() to always be called on minor faults. This patch reworks ptep_set_access_flags() semantics, implementations and callers so that it's now responsible for returning whether an update is necessary or not (basically whether the PTE actually changed). This allow fixing the sparc implementation to always return 1 on sun4c. [akpm@linux-foundation.org: fixes, cleanups] Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Hugh Dickins <hugh@veritas.com> Cc: David Miller <davem@davemloft.net> Cc: Mark Fortescue <mark@mtfhpc.demon.co.uk> Acked-by: William Lee Irwin III <wli@holomorphy.com> Cc: "Luck, Tony" <tony.luck@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/mm/memory.c b/mm/memory.c
index cb94488ab96..f64cbf9baa3 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1691,9 +1691,10 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
1691 flush_cache_page(vma, address, pte_pfn(orig_pte)); 1691 flush_cache_page(vma, address, pte_pfn(orig_pte));
1692 entry = pte_mkyoung(orig_pte); 1692 entry = pte_mkyoung(orig_pte);
1693 entry = maybe_mkwrite(pte_mkdirty(entry), vma); 1693 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
1694 ptep_set_access_flags(vma, address, page_table, entry, 1); 1694 if (ptep_set_access_flags(vma, address, page_table, entry,1)) {
1695 update_mmu_cache(vma, address, entry); 1695 update_mmu_cache(vma, address, entry);
1696 lazy_mmu_prot_update(entry); 1696 lazy_mmu_prot_update(entry);
1697 }
1697 ret |= VM_FAULT_WRITE; 1698 ret |= VM_FAULT_WRITE;
1698 goto unlock; 1699 goto unlock;
1699 } 1700 }
@@ -2525,10 +2526,9 @@ static inline int handle_pte_fault(struct mm_struct *mm,
2525 pte_t *pte, pmd_t *pmd, int write_access) 2526 pte_t *pte, pmd_t *pmd, int write_access)
2526{ 2527{
2527 pte_t entry; 2528 pte_t entry;
2528 pte_t old_entry;
2529 spinlock_t *ptl; 2529 spinlock_t *ptl;
2530 2530
2531 old_entry = entry = *pte; 2531 entry = *pte;
2532 if (!pte_present(entry)) { 2532 if (!pte_present(entry)) {
2533 if (pte_none(entry)) { 2533 if (pte_none(entry)) {
2534 if (vma->vm_ops) { 2534 if (vma->vm_ops) {
@@ -2561,8 +2561,7 @@ static inline int handle_pte_fault(struct mm_struct *mm,
2561 entry = pte_mkdirty(entry); 2561 entry = pte_mkdirty(entry);
2562 } 2562 }
2563 entry = pte_mkyoung(entry); 2563 entry = pte_mkyoung(entry);
2564 if (!pte_same(old_entry, entry)) { 2564 if (ptep_set_access_flags(vma, address, pte, entry, write_access)) {
2565 ptep_set_access_flags(vma, address, pte, entry, write_access);
2566 update_mmu_cache(vma, address, entry); 2565 update_mmu_cache(vma, address, entry);
2567 lazy_mmu_prot_update(entry); 2566 lazy_mmu_prot_update(entry);
2568 } else { 2567 } else {