Add ability to remove migration ptes. 1. Modify page_check_address to support matching on ptes with SWP_TYPE_MIGRATION 2. Add functions to scan the anon vma and replace SWAP_TYPE_MIGRATION ptes with regular ones. Signed-off-by: Christoph Lameter Index: linux-2.6.17-rc1/include/linux/rmap.h =================================================================== --- linux-2.6.17-rc1.orig/include/linux/rmap.h 2006-04-02 20:22:10.000000000 -0700 +++ linux-2.6.17-rc1/include/linux/rmap.h 2006-04-06 11:31:48.407380000 -0700 @@ -105,6 +105,11 @@ pte_t *page_check_address(struct page *, */ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); +/* + * Used by page migration to restore ptes of anonymous pages + */ +void remove_migration_ptes(struct page *page, struct page *newpage); + #else /* !CONFIG_MMU */ #define anon_vma_init() do {} while (0) Index: linux-2.6.17-rc1/mm/rmap.c =================================================================== --- linux-2.6.17-rc1.orig/mm/rmap.c 2006-04-06 11:09:14.617856000 -0700 +++ linux-2.6.17-rc1/mm/rmap.c 2006-04-06 21:50:43.608324000 -0700 @@ -323,6 +323,43 @@ pte_t *page_check_address(struct page *p return NULL; } +#ifdef CONFIG_MIGRATION +/* + * Get rid of all migration entries and replace them by + * references to the indicated page. + * + * Must hold mmap_sem lock on at least one of the vmas containing + * the page so that the anon_vma cannot vanish. + */ +void enable_ptes(struct page *page, struct page *newpage) +{ + struct anon_vma *anon_vma; + struct vm_area_struct *vma; + spinlock_t ptl; + + if (!PageAnon(newpage)) + return; + + anon_vma = page_lock_anon_vma(newpage); + BUG_ON(!anon_vma); + + list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { + spinlock_t ptl; + pte_t *pte; + + pte = page_check_address(page, vma->vm_mm, + page_address_in_vma(newpage, vma), &ptl); + + if (pte) { + __put_page(page); + get_page(newpage); + pte_enable(pte); + spin_unlock(ptl); + } + } + spin_unlock(&anon_vma->lock); +} +#endif /* * Subfunctions of page_referenced: page_referenced_one called * repeatedly from either page_referenced_anon or page_referenced_file.