diff options
| author | Hugh Dickins <hugh@veritas.com> | 2007-06-16 13:15:59 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-16 16:16:15 -0400 |
| commit | d6f8bb1310d4745ff1d0c74eeacae31e2a3eeff1 (patch) | |
| tree | 4048f434ec97b0b0415e3937c1e42be9cb6ca378 /include | |
| parent | 30475cc12a50816f290828fb7e3cd7036cd622df (diff) | |
i386 mm: use pte_update() in ptep_test_and_clear_dirty()
It is not safe to use pte_update_defer() in ptep_test_and_clear_young():
its only user, /proc/<pid>/clear_refs, drops pte lock before flushing TLB.
Use the safe though less efficient pte_update() paravirtop in its place.
Likewise in ptep_test_and_clear_dirty(), though that has no current use.
These are macros (header file dependency stops them from becoming inline
functions), so be more liberal with the underscores and parentheses.
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-i386/pgtable.h | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/include/asm-i386/pgtable.h b/include/asm-i386/pgtable.h index 2394589786ba..d62bdb029efa 100644 --- a/include/asm-i386/pgtable.h +++ b/include/asm-i386/pgtable.h | |||
| @@ -295,22 +295,24 @@ do { \ | |||
| 295 | 295 | ||
| 296 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY | 296 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY |
| 297 | #define ptep_test_and_clear_dirty(vma, addr, ptep) ({ \ | 297 | #define ptep_test_and_clear_dirty(vma, addr, ptep) ({ \ |
| 298 | int ret = 0; \ | 298 | int __ret = 0; \ |
| 299 | if (pte_dirty(*ptep)) \ | 299 | if (pte_dirty(*(ptep))) \ |
| 300 | ret = test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); \ | 300 | __ret = test_and_clear_bit(_PAGE_BIT_DIRTY, \ |
| 301 | if (ret) \ | 301 | &(ptep)->pte_low); \ |
| 302 | pte_update_defer(vma->vm_mm, addr, ptep); \ | 302 | if (__ret) \ |
| 303 | ret; \ | 303 | pte_update((vma)->vm_mm, addr, ptep); \ |
| 304 | __ret; \ | ||
| 304 | }) | 305 | }) |
| 305 | 306 | ||
| 306 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | 307 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG |
| 307 | #define ptep_test_and_clear_young(vma, addr, ptep) ({ \ | 308 | #define ptep_test_and_clear_young(vma, addr, ptep) ({ \ |
| 308 | int ret = 0; \ | 309 | int __ret = 0; \ |
| 309 | if (pte_young(*ptep)) \ | 310 | if (pte_young(*(ptep))) \ |
| 310 | ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low); \ | 311 | __ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, \ |
| 311 | if (ret) \ | 312 | &(ptep)->pte_low); \ |
| 312 | pte_update_defer(vma->vm_mm, addr, ptep); \ | 313 | if (__ret) \ |
| 313 | ret; \ | 314 | pte_update((vma)->vm_mm, addr, ptep); \ |
| 315 | __ret; \ | ||
| 314 | }) | 316 | }) |
| 315 | 317 | ||
| 316 | /* | 318 | /* |
