On Sun, 25 Mar 2007 23:37:08 -0700 (PDT) David Rientjes <[EMAIL PROTECTED]> wrote:
> Date: Sun, 25 Mar 2007 23:07:43 -0800 > From: Zachary Amsden <[EMAIL PROTECTED]> > > If you actually clear the bit, you need to: > > + pte_update_defer(vma->vm_mm, addr, ptep); > > The reason is, when updating PTEs, the hypervisor must be notified. > Using > atomic operations to do this is fine for all hypervisors I am aware of. > However, for hypervisors which shadow page tables, if these PTE > modifications are not trapped, you need a post-modification call to > fulfill > the update of the shadow page table. > > Cc: Zachary Amsden <[EMAIL PROTECTED]> > Cc: Hugh Dickins <[EMAIL PROTECTED]> > Signed-off-by: David Rientjes <[EMAIL PROTECTED]> > --- > 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 > --- a/include/asm-i386/pgtable.h > +++ b/include/asm-i386/pgtable.h > @@ -287,18 +287,24 @@ do { > \ > static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, > unsigned long addr, pte_t *ptep) > { > - if (!pte_dirty(*ptep)) > - return 0; > - return test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); > + int ret = 0; > + if (pte_dirty(*ptep)) > + ret = test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); > + if (ret) > + pte_update_defer(vma->vm_mm, addr, ptep); > + return ret; > } > i386 allmodconfig: include/asm/pgtable.h: In function 'ptep_test_and_clear_dirty': include/asm/pgtable.h:294: error: dereferencing pointer to incomplete type include/asm/pgtable.h: In function 'ptep_test_and_clear_young': include/asm/pgtable.h:306: error: dereferencing pointer to incomplete type Due to vm_area_struct. Turning it into a stinky macro fixes it. diff -puN include/asm-i386/pgtable.h~i386-use-pte_update_defer-in-ptep_test_and_clear_dirtyyoung-fix include/asm-i386/pgtable.h --- a/include/asm-i386/pgtable.h~i386-use-pte_update_defer-in-ptep_test_and_clear_dirtyyoung-fix +++ a/include/asm-i386/pgtable.h @@ -284,28 +284,24 @@ do { \ } while (0) #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY -static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) -{ - int ret = 0; - if (pte_dirty(*ptep)) - ret = test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); - if (ret) - pte_update_defer(vma->vm_mm, addr, ptep); - return ret; -} +#define ptep_test_and_clear_dirty(vma, addr, ptep) ({ \ + int ret = 0; \ + if (pte_dirty(*ptep)) \ + ret = test_and_clear_bit(_PAGE_BIT_DIRTY, &ptep->pte_low); \ + if (ret) \ + pte_update_defer(vma->vm_mm, addr, ptep); \ + ret; \ +}) #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG -static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) -{ - int ret = 0; - if (pte_young(*ptep)) - ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low); - if (ret) - pte_update_defer(vma->vm_mm, addr, ptep); - return ret; -} +#define ptep_test_and_clear_young(vma, addr, ptep) ({ \ + int ret = 0; \ + if (pte_young(*ptep)) \ + ret = test_and_clear_bit(_PAGE_BIT_ACCESSED, &ptep->pte_low); \ + if (ret) \ + pte_update_defer(vma->vm_mm, addr, ptep); \ + ret; \ +}) /* * Rules for using ptep_establish: the pte MUST be a user pte, and _ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/