--- include/linux/mmu_notifier.h | 24 ------------------------ mm/filemap_xip.c | 5 +++-- mm/memory.c | 6 ++++-- mm/mmu_notifier.c | 11 ----------- mm/rmap.c | 14 ++++++++------ 5 files changed, 15 insertions(+), 45 deletions(-) Index: linux-2.6/include/linux/mmu_notifier.h =================================================================== --- linux-2.6.orig/include/linux/mmu_notifier.h 2008-04-17 17:32:18.000000000 -0700 +++ linux-2.6/include/linux/mmu_notifier.h 2008-04-17 17:33:21.000000000 -0700 @@ -30,16 +30,6 @@ struct mmu_notifier_ops { unsigned long address); /* - * Before this is invoked any secondary MMU is still ok to - * read/write to the page previously pointed by the Linux pte - * because the old page hasn't been freed yet. If required - * set_page_dirty has to be called internally to this method. - */ - void (*invalidate_page)(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long address); - - /* * invalidate_range_start() and invalidate_range_end() must be * paired. Multiple invalidate_range_start/ends may be nested * or called concurrently. @@ -69,8 +59,6 @@ extern int mmu_notifier_unregister(struc extern void __mmu_notifier_release(struct mm_struct *mm); extern int __mmu_notifier_clear_flush_young(struct mm_struct *mm, unsigned long address); -extern void __mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address); extern void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end); extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, @@ -91,13 +79,6 @@ static inline int mmu_notifier_clear_flu return 0; } -static inline void mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address) -{ - if (mm_has_notifiers(mm)) - __mmu_notifier_invalidate_page(mm, address); -} - static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end) { @@ -129,11 +110,6 @@ static inline int mmu_notifier_clear_flu return 0; } -static inline void mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address) -{ -} - static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end) { Index: linux-2.6/mm/filemap_xip.c =================================================================== --- linux-2.6.orig/mm/filemap_xip.c 2008-04-17 17:34:35.000000000 -0700 +++ linux-2.6/mm/filemap_xip.c 2008-04-17 17:39:31.000000000 -0700 @@ -15,6 +15,7 @@ #include #include #include +#include /* * We do use our own empty page to avoid interference with other users @@ -192,6 +193,7 @@ __xip_unmap (struct address_space * mapp BUG_ON(address < vma->vm_start || address >= vma->vm_end); pte = page_check_address(page, mm, address, &ptl); if (pte) { + mmu_notifier_invalidate_range_start(mm, address, address + PAGE_SIZE); /* Nuke the page table entry. */ flush_cache_page(vma, address, pte_pfn(*pte)); pteval = ptep_clear_flush(vma, address, pte); @@ -199,9 +201,8 @@ __xip_unmap (struct address_space * mapp dec_mm_counter(mm, file_rss); BUG_ON(pte_dirty(pteval)); pte_unmap_unlock(pte, ptl); - /* must invalidate_page _before_ freeing the page */ - mmu_notifier_invalidate_page(mm, address); page_cache_release(page); + mmu_notifier_invalidate_range_end(mm, address, address + PAGE_SIZE); } } up_read(&mapping->i_mmap_sem); Index: linux-2.6/mm/memory.c =================================================================== --- linux-2.6.orig/mm/memory.c 2008-04-17 17:39:57.000000000 -0700 +++ linux-2.6/mm/memory.c 2008-04-17 17:43:04.000000000 -0700 @@ -1696,9 +1696,11 @@ unlock: pte_unmap_unlock(page_table, ptl); if (new_page) { - if (new_page == old_page) + if (new_page == old_page) { /* cow happened, notify before releasing old_page */ - mmu_notifier_invalidate_page(mm, address); + mmu_notifier_invalidate_range_start(mm, address, address + PAGE_SIZE); + mmu_notifier_invalidate_range_end(mm, address, address + PAGE_SIZE); + } page_cache_release(new_page); } if (old_page) Index: linux-2.6/mm/mmu_notifier.c =================================================================== --- linux-2.6.orig/mm/mmu_notifier.c 2008-04-17 17:33:30.000000000 -0700 +++ linux-2.6/mm/mmu_notifier.c 2008-04-17 17:34:10.000000000 -0700 @@ -51,17 +51,6 @@ int __mmu_notifier_clear_flush_young(str return young; } -void __mmu_notifier_invalidate_page(struct mm_struct *mm, - unsigned long address) -{ - struct mmu_notifier *mn; - - list_for_each_entry(mn, &mm->mmu_notifier_list, list) { - if (mn->ops->invalidate_page) - mn->ops->invalidate_page(mn, mm, address); - } -} - void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, unsigned long start, unsigned long end) { Index: linux-2.6/mm/rmap.c =================================================================== --- linux-2.6.orig/mm/rmap.c 2008-04-17 17:43:11.000000000 -0700 +++ linux-2.6/mm/rmap.c 2008-04-17 17:47:54.000000000 -0700 @@ -465,9 +465,10 @@ static int page_mkclean_one(struct page if (address == -EFAULT) goto out; + mmu_notifier_invalidate_range_start(mm, address, address + PAGE_SIZE); pte = page_check_address(page, mm, address, &ptl); if (!pte) - goto out; + goto out_notifier; if (pte_dirty(*pte) || pte_write(*pte)) { pte_t entry; @@ -482,8 +483,8 @@ static int page_mkclean_one(struct page pte_unmap_unlock(pte, ptl); - if (ret) - mmu_notifier_invalidate_page(mm, address); +out_notifier: + mmu_notifier_invalidate_range_start(mm, address, address + PAGE_SIZE); out: return ret; @@ -728,9 +729,10 @@ static int try_to_unmap_one(struct page if (address == -EFAULT) goto out; + mmu_notifier_invalidate_range_start(mm, address, address + PAGE_SIZE); pte = page_check_address(page, mm, address, &ptl); if (!pte) - goto out; + goto out_notifier; /* * If the page is mlock()d, we cannot swap it out. @@ -799,8 +801,8 @@ static int try_to_unmap_one(struct page out_unmap: pte_unmap_unlock(pte, ptl); - if (ret != SWAP_FAIL) - mmu_notifier_invalidate_page(mm, address); +out_notifier: + mmu_notifier_invalidate_range_start(mm, address, address + PAGE_SIZE); out: return ret; }