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 | |
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>
-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 | /* |