The patch titled
     Rework ptep_set_access_flags and fix sun4c
has been added to the -mm tree.  Its filename is
     rework-ptep_set_access_flags-and-fix-sun4c.patch

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: Rework ptep_set_access_flags and fix sun4c
From: Benjamin Herrenschmidt <[EMAIL PROTECTED]>

This patch reworks ptep_set_access_flags() and the callers so that the
comparison to the old PTE is done inside that function, which then returns
wether an update_mmu_cache() is needed.  That allows fixing the sun4c
situation where update_mmu_cache() needs to be forced, always.

(akpm: ugh, I merged version 4,324.  This is version 4,325)

Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]>
Cc: Hugh Dickins <[EMAIL PROTECTED]>
Cc: David Miller <[EMAIL PROTECTED]>
Cc: Mark Fortescue <[EMAIL PROTECTED]>
Cc: William Lee Irwin III <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---

 include/asm-generic/pgtable.h       |   17 ++++++++++++-----
 include/asm-i386/pgtable.h          |    8 +++++---
 include/asm-ia64/pgtable.h          |   25 ++++++++++++++++---------
 include/asm-powerpc/pgtable-ppc32.h |   12 ++++++++----
 include/asm-powerpc/pgtable-ppc64.h |   12 ++++++++----
 include/asm-ppc/pgtable.h           |   12 ++++++++----
 include/asm-s390/pgtable.h          |    7 ++++++-
 include/asm-sparc/pgtable.h         |   11 +++++++++++
 include/asm-x86_64/pgtable.h        |   14 ++++++++------
 mm/hugetlb.c                        |    7 ++++---
 mm/memory.c                         |   13 ++++++-------
 11 files changed, 92 insertions(+), 46 deletions(-)

diff -puN 
include/asm-generic/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-generic/pgtable.h
--- a/include/asm-generic/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-generic/pgtable.h
@@ -27,13 +27,20 @@ do {                                                        
                \
  * Largely same as above, but only sets the access flags (dirty,
  * accessed, and writable). Furthermore, we know it always gets set
  * to a "more permissive" setting, which allows most architectures
- * to optimize this.
+ * to optimize this. We return whether the PTE actually changed, which
+ * in turn instructs the caller to do things like update__mmu_cache.
+ * This used to be done in the caller, but sparc needs minor faults to
+ * force that call on sun4c so we changed this macro slightly
  */
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-do {                                                                     \
-       set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);         \
-       flush_tlb_page(__vma, __address);                                 \
-} while (0)
+({                                                                       \
+       int __changed = !pte_same(*(__ptep), __entry);                    \
+       if (__changed) {                                                  \
+               set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
+               flush_tlb_page(__vma, __address);                         \
+       }                                                                 \
+       __changed;                                                        \
+})
 #endif
 
 #ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
diff -puN include/asm-i386/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-i386/pgtable.h
--- a/include/asm-i386/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-i386/pgtable.h
@@ -285,13 +285,15 @@ static inline pte_t native_local_ptep_ge
  */
 #define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(vma, address, ptep, entry, dirty)                
\
-do {                                                                   \
-       if (dirty) {                                                    \
+({                                                                     \
+       int __changed = !pte_same(*(ptep), entry);                      \
+       if (__changed && dirty) {                                       \
                (ptep)->pte_low = (entry).pte_low;                      \
                pte_update_defer((vma)->vm_mm, (address), (ptep));      \
                flush_tlb_page(vma, address);                           \
        }                                                               \
-} while (0)
+       __changed;                                                      \
+})
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
 #define ptep_test_and_clear_dirty(vma, addr, ptep) ({                  \
diff -puN include/asm-ia64/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-ia64/pgtable.h
--- a/include/asm-ia64/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-ia64/pgtable.h
@@ -533,16 +533,23 @@ extern void lazy_mmu_prot_update (pte_t 
  * daccess_bit in ivt.S).
  */
 #ifdef CONFIG_SMP
-# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, 
__safely_writable)      \
-do {                                                                           
        \
-       if (__safely_writable) {                                                
        \
-               set_pte(__ptep, __entry);                                       
        \
-               flush_tlb_page(__vma, __addr);                                  
        \
-       }                                                                       
        \
-} while (0)
+# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, 
__safely_writable) \
+({                                                                             
\
+       int __changed = !pte_same(*(__ptep), __entry);                          
\
+       if (__changed && __safely_writable) {                                   
\
+               set_pte(__ptep, __entry);                                       
\
+               flush_tlb_page(__vma, __addr);                                  
\
+       }                                                                       
\
+       __changed;                                                              
\
+})
 #else
-# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, 
__safely_writable)      \
-       ptep_establish(__vma, __addr, __ptep, __entry)
+# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, 
__safely_writable) \
+({                                                                             
\
+       int __changed = !pte_same(*(__ptep), __entry);                          
\
+       if (__changed) {                                                        
\
+               ptep_establish(__vma, __addr, __ptep, __entry)                  
\
+       __changed;                                                              
\
+})
 #endif
 
 #  ifdef CONFIG_VIRTUAL_MEM_MAP
diff -puN 
include/asm-powerpc/pgtable-ppc32.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-powerpc/pgtable-ppc32.h
--- 
a/include/asm-powerpc/pgtable-ppc32.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-powerpc/pgtable-ppc32.h
@@ -673,10 +673,14 @@ static inline void __ptep_set_access_fla
 }
 
 #define  ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-       do {                                                               \
-               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
-               flush_tlb_page_nohash(__vma, __address);                   \
-       } while(0)
+({                                                                        \
+       int __changed = !pte_same(*(__ptep), __entry);                     \
+       if (__changed) {                                                   \
+               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
+               flush_tlb_page_nohash(__vma, __address);                   \
+       }                                                                  \
+       __changed;                                                         \
+})
 
 /*
  * Macro to mark a page protection value as "uncacheable".
diff -puN 
include/asm-powerpc/pgtable-ppc64.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-powerpc/pgtable-ppc64.h
--- 
a/include/asm-powerpc/pgtable-ppc64.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-powerpc/pgtable-ppc64.h
@@ -413,10 +413,14 @@ static inline void __ptep_set_access_fla
        :"cc");
 }
 #define  ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-       do {                                                               \
-               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
-               flush_tlb_page_nohash(__vma, __address);                   \
-       } while(0)
+({                                                                        \
+       int __changed = !pte_same(*(__ptep), __entry);                     \
+       if (__changed) {                                                   \
+               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
+               flush_tlb_page_nohash(__vma, __address);                   \
+       }                                                                  \
+       __changed;                                                         \
+})
 
 /*
  * Macro to mark a page protection value as "uncacheable".
diff -puN include/asm-ppc/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-ppc/pgtable.h
--- a/include/asm-ppc/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-ppc/pgtable.h
@@ -694,10 +694,14 @@ static inline void __ptep_set_access_fla
 }
 
 #define  ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-       do {                                                               \
-               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
-               flush_tlb_page_nohash(__vma, __address);                   \
-       } while(0)
+({                                                                        \
+       int __changed = !pte_same(*(__ptep), __entry);                     \
+       if (__changed) {                                                   \
+               __ptep_set_access_flags(__ptep, __entry, __dirty);         \
+               flush_tlb_page_nohash(__vma, __address);                   \
+       }                                                                  \
+       __changed;                                                         \
+})
 
 /*
  * Macro to mark a page protection value as "uncacheable".
diff -puN include/asm-s390/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-s390/pgtable.h
--- a/include/asm-s390/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-s390/pgtable.h
@@ -744,7 +744,12 @@ ptep_establish(struct vm_area_struct *vm
 }
 
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-       ptep_establish(__vma, __address, __ptep, __entry)
+({                                                                       \
+       int __changed = !pte_same(*(__ptep), __entry);                    \
+       if (__changed)                                                    \
+               ptep_establish(__vma, __address, __ptep, __entry);        \
+       __changed;                                                        \
+})
 
 /*
  * Test and clear dirty bit in storage key.
diff -puN 
include/asm-sparc/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-sparc/pgtable.h
--- a/include/asm-sparc/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-sparc/pgtable.h
@@ -446,6 +446,17 @@ extern int io_remap_pfn_range(struct vm_
 #define GET_IOSPACE(pfn)               (pfn >> (BITS_PER_LONG - 4))
 #define GET_PFN(pfn)                   (pfn & 0x0fffffffUL)
 
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
+({                                                                       \
+       int __changed = !pte_same(*(__ptep), __entry);                    \
+       if (__changed) {                                                  \
+               set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry); \
+               flush_tlb_page(__vma, __address);                         \
+       }                                                                 \
+       (sparc_cpu_model == sun4c) || __changed;                          \
+})
+
 #include <asm-generic/pgtable.h>
 
 #endif /* !(__ASSEMBLY__) */
diff -puN 
include/asm-x86_64/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c 
include/asm-x86_64/pgtable.h
--- a/include/asm-x86_64/pgtable.h~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/include/asm-x86_64/pgtable.h
@@ -395,12 +395,14 @@ static inline pte_t pte_modify(pte_t pte
  * bit at the same time. */
 #define  __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
 #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \
-       do {                                                              \
-               if (__dirty) {                                            \
-                       set_pte(__ptep, __entry);                         \
-                       flush_tlb_page(__vma, __address);                 \
-               }                                                         \
-       } while (0)
+({                                                                       \
+       int __changed = !pte_same(*(__ptep), __entry);                    \
+       if (__changed && __dirty) {                                       \
+               set_pte(__ptep, __entry);                                 \
+               flush_tlb_page(__vma, __address);                         \
+       }                                                                 \
+       __changed;                                                        \
+})
 
 /* Encode and de-code a swap entry */
 #define __swp_type(x)                  (((x).val >> 1) & 0x3f)
diff -puN mm/hugetlb.c~rework-ptep_set_access_flags-and-fix-sun4c mm/hugetlb.c
--- a/mm/hugetlb.c~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/mm/hugetlb.c
@@ -325,9 +325,10 @@ static void set_huge_ptep_writable(struc
        pte_t entry;
 
        entry = pte_mkwrite(pte_mkdirty(*ptep));
-       ptep_set_access_flags(vma, address, ptep, entry, 1);
-       update_mmu_cache(vma, address, entry);
-       lazy_mmu_prot_update(entry);
+       if (ptep_set_access_flags(vma, address, ptep, entry, 1)) {
+               update_mmu_cache(vma, address, entry);
+               lazy_mmu_prot_update(entry);
+       }
 }
 
 
diff -puN mm/memory.c~rework-ptep_set_access_flags-and-fix-sun4c mm/memory.c
--- a/mm/memory.c~rework-ptep_set_access_flags-and-fix-sun4c
+++ a/mm/memory.c
@@ -1697,9 +1697,10 @@ static int do_wp_page(struct mm_struct *
                flush_cache_page(vma, address, pte_pfn(orig_pte));
                entry = pte_mkyoung(orig_pte);
                entry = maybe_mkwrite(pte_mkdirty(entry), vma);
-               ptep_set_access_flags(vma, address, page_table, entry, 1);
-               update_mmu_cache(vma, address, entry);
-               lazy_mmu_prot_update(entry);
+               if (ptep_set_access_flags(vma, address, page_table, entry,1)) {
+                       update_mmu_cache(vma, address, entry);
+                       lazy_mmu_prot_update(entry);
+               }
                ret |= VM_FAULT_WRITE;
                goto unlock;
        }
@@ -2508,10 +2509,9 @@ static inline int handle_pte_fault(struc
                pte_t *pte, pmd_t *pmd, int write_access)
 {
        pte_t entry;
-       pte_t old_entry;
        spinlock_t *ptl;
 
-       old_entry = entry = *pte;
+       entry = *pte;
        if (!pte_present(entry)) {
                if (pte_none(entry)) {
                        if (vma->vm_ops) {
@@ -2540,8 +2540,7 @@ static inline int handle_pte_fault(struc
                entry = pte_mkdirty(entry);
        }
        entry = pte_mkyoung(entry);
-       if (!pte_same(old_entry, entry)) {
-               ptep_set_access_flags(vma, address, pte, entry, write_access);
+       if (ptep_set_access_flags(vma, address, pte, entry, write_access)) {
                update_mmu_cache(vma, address, entry);
                lazy_mmu_prot_update(entry);
        } else {
_

Patches currently in -mm which might be from [EMAIL PROTECTED] are

powerpc-fix.patch
do-not-select-macintosh-drivers-by-default.patch
8xx-mpc885ads-pcmcia-support.patch
8xx-mpc885ads-pcmcia-support-fix.patch
8xx-fix-whitespace-and-indentation.patch
dts-kill-hardcoded-phandles.patch
git-libata-all.patch
rework-ptep_set_access_flags-and-fix-sun4c.patch
fallocate-implementation-on-i86-x86_64-and-powerpc.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to