x86: cpa, check if we changed anything and tlb flushing is necessary
authorThomas Gleixner <tglx@linutronix.de>
Mon, 4 Feb 2008 15:48:07 +0000 (16:48 +0100)
committerIngo Molnar <mingo@elte.hu>
Mon, 4 Feb 2008 15:48:07 +0000 (16:48 +0100)
Flush tlbs only when there was a real change.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/mm/pageattr.c

index d1c08308ecbbba955d4b29c266f01ff96f8b55aa..79a9f1b42ddd60c5d0f24290b691eaba5021514d 100644 (file)
@@ -21,6 +21,7 @@ struct cpa_data {
        int             numpages;
        pgprot_t        mask_set;
        pgprot_t        mask_clr;
+       int             flushtlb;
 };
 
 static inline int
@@ -329,11 +330,19 @@ repeat:
                 * not the memory it points to
                 */
                new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot));
-               set_pte_atomic(kpte, new_pte);
+
+               /*
+                * Do we really change anything ?
+                */
+               if (pte_val(old_pte) != pte_val(new_pte)) {
+                       set_pte_atomic(kpte, new_pte);
+                       cpa->flushtlb = 1;
+               }
        } else {
                err = split_large_page(kpte, address);
                if (!err)
                        goto repeat;
+               cpa->flushtlb = 1;
        }
        return err;
 }
@@ -438,9 +447,16 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
        cpa.numpages = numpages;
        cpa.mask_set = mask_set;
        cpa.mask_clr = mask_clr;
+       cpa.flushtlb = 0;
 
        ret = __change_page_attr_set_clr(&cpa);
 
+       /*
+        * Check whether we really changed something:
+        */
+       if (!cpa.flushtlb)
+               return ret;
+
        /*
         * No need to flush, when we did not set any of the caching
         * attributes: