[PATCH] pretest pte_young and pte_dirty

From: Hugh Dickins
Date: Wed Jun 02 2004 - 15:22:59 EST


Test for pte_young before going to the costlier atomic test_and_clear,
as asm-generic does. Test for pte_dirty before going to the costlier
atomic test_and_clear, as asm-generic does (I said before that I would
not do so for pte_dirty, but was missing the point: there is nothing
atomic about deciding to do nothing). But I've not touched the rather
different ppc and ppc64.

Signed-off-by: Hugh Dickins <hugh@xxxxxxxxxxx>

include/asm-i386/pgtable.h | 16 ++++++++++++++--
include/asm-ia64/pgtable.h | 4 ++++
include/asm-parisc/pgtable.h | 4 ++++
include/asm-x86_64/pgtable.h | 17 +++++++++++++++--
4 files changed, 37 insertions(+), 4 deletions(-)

--- 2.6.7-rc2/include/asm-i386/pgtable.h 2004-05-30 11:36:30.000000000 +0100
+++ linux/include/asm-i386/pgtable.h 2004-06-02 16:32:40.032214544 +0100
@@ -220,8 +220,20 @@ static inline pte_t pte_mkdirty(pte_t pt
static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }

-static inline int ptep_test_and_clear_dirty(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }
-static inline int ptep_test_and_clear_young(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low); }
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+ if (!pte_dirty(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low);
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+ if (!pte_young(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low);
+}
+
static inline void ptep_set_wrprotect(pte_t *ptep) { clear_bit(_PAGE_BIT_RW, &ptep->pte_low); }
static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); }

--- 2.6.7-rc2/include/asm-ia64/pgtable.h 2004-05-30 11:36:31.000000000 +0100
+++ linux/include/asm-ia64/pgtable.h 2004-06-02 16:32:40.034214240 +0100
@@ -346,6 +346,8 @@ static inline int
ptep_test_and_clear_young (pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_young(*ptep))
+ return 0;
return test_and_clear_bit(_PAGE_A_BIT, ptep);
#else
pte_t pte = *ptep;
@@ -360,6 +362,8 @@ static inline int
ptep_test_and_clear_dirty (pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_dirty(*ptep))
+ return 0;
return test_and_clear_bit(_PAGE_D_BIT, ptep);
#else
pte_t pte = *ptep;
--- 2.6.7-rc2/include/asm-parisc/pgtable.h 2004-05-30 11:36:33.000000000 +0100
+++ linux/include/asm-parisc/pgtable.h 2004-06-02 16:32:40.035214088 +0100
@@ -417,6 +417,8 @@ extern void update_mmu_cache(struct vm_a
static inline int ptep_test_and_clear_young(pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_young(*ptep))
+ return 0;
return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), ptep);
#else
pte_t pte = *ptep;
@@ -430,6 +432,8 @@ static inline int ptep_test_and_clear_yo
static inline int ptep_test_and_clear_dirty(pte_t *ptep)
{
#ifdef CONFIG_SMP
+ if (!pte_dirty(*ptep))
+ return 0;
return test_and_clear_bit(xlate_pabit(_PAGE_DIRTY_BIT), ptep);
#else
pte_t pte = *ptep;
--- 2.6.7-rc2/include/asm-x86_64/pgtable.h 2004-05-30 11:36:35.000000000 +0100
+++ linux/include/asm-x86_64/pgtable.h 2004-06-02 16:32:40.036213936 +0100
@@ -262,8 +262,21 @@ extern inline pte_t pte_mkexec(pte_t pte
extern inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
extern inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
extern inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
-static inline int ptep_test_and_clear_dirty(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep); }
-static inline int ptep_test_and_clear_young(pte_t *ptep) { return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); }
+
+static inline int ptep_test_and_clear_dirty(pte_t *ptep)
+{
+ if (!pte_dirty(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep);
+}
+
+static inline int ptep_test_and_clear_young(pte_t *ptep)
+{
+ if (!pte_young(*ptep))
+ return 0;
+ return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
+}
+
static inline void ptep_set_wrprotect(pte_t *ptep) { clear_bit(_PAGE_BIT_RW, ptep); }
static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, ptep); }


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/