diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2008-02-04 10:48:07 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-02-04 10:48:07 -0500 |
| commit | f4ae5da0e8e92caa168e7c2a7c4a6c4064b082c2 (patch) | |
| tree | f4b3a98c7e9ea6d158bdc5bf5a479eaeb93c6957 | |
| parent | 72e458dfa63b3db7a46f66b0eb19e9ff4e17fc0e (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.c | 18 |
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 | ||
| 26 | static inline int | 27 | static 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 | */ |
