aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-02-04 10:48:07 -0500
committerIngo Molnar <mingo@elte.hu>2008-02-04 10:48:07 -0500
commitf4ae5da0e8e92caa168e7c2a7c4a6c4064b082c2 (patch)
treef4b3a98c7e9ea6d158bdc5bf5a479eaeb93c6957
parent72e458dfa63b3db7a46f66b0eb19e9ff4e17fc0e (diff)
x86: cpa, check if we changed anything and tlb flushing is necessary
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>
-rw-r--r--arch/x86/mm/pageattr.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index d1c08308ecbb..79a9f1b42ddd 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -21,6 +21,7 @@ struct cpa_data {
21 int numpages; 21 int numpages;
22 pgprot_t mask_set; 22 pgprot_t mask_set;
23 pgprot_t mask_clr; 23 pgprot_t mask_clr;
24 int flushtlb;
24}; 25};
25 26
26static inline int 27static inline int
@@ -329,11 +330,19 @@ repeat:
329 * not the memory it points to 330 * not the memory it points to
330 */ 331 */
331 new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot)); 332 new_pte = pfn_pte(pte_pfn(old_pte), canon_pgprot(new_prot));
332 set_pte_atomic(kpte, new_pte); 333
334 /*
335 * Do we really change anything ?
336 */
337 if (pte_val(old_pte) != pte_val(new_pte)) {
338 set_pte_atomic(kpte, new_pte);
339 cpa->flushtlb = 1;
340 }
333 } else { 341 } else {
334 err = split_large_page(kpte, address); 342 err = split_large_page(kpte, address);
335 if (!err) 343 if (!err)
336 goto repeat; 344 goto repeat;
345 cpa->flushtlb = 1;
337 } 346 }
338 return err; 347 return err;
339} 348}
@@ -438,10 +447,17 @@ static int change_page_attr_set_clr(unsigned long addr, int numpages,
438 cpa.numpages = numpages; 447 cpa.numpages = numpages;
439 cpa.mask_set = mask_set; 448 cpa.mask_set = mask_set;
440 cpa.mask_clr = mask_clr; 449 cpa.mask_clr = mask_clr;
450 cpa.flushtlb = 0;
441 451
442 ret = __change_page_attr_set_clr(&cpa); 452 ret = __change_page_attr_set_clr(&cpa);
443 453
444 /* 454 /*
455 * Check whether we really changed something:
456 */
457 if (!cpa.flushtlb)
458 return ret;
459
460 /*
445 * No need to flush, when we did not set any of the caching 461 * No need to flush, when we did not set any of the caching
446 * attributes: 462 * attributes:
447 */ 463 */