When a page happen to be migrated, a stale page might be caught from a radix-tree. In this case a proper page has to be got from the radix-tree again. Signed-off-by: Hirokazu Takahashi Signed-off-by: Dave Hansen --- memhotplug-dave/mm/memory.c | 7 +++++++ memhotplug-dave/mm/shmem.c | 8 ++++++++ memhotplug-dave/mm/swapfile.c | 7 +++++++ 3 files changed, 22 insertions(+) diff -puN mm/memory.c~AA-PM-09-migrate-swapcache-validate mm/memory.c --- memhotplug/mm/memory.c~AA-PM-09-migrate-swapcache-validate 2005-07-28 13:50:37.000000000 -0700 +++ memhotplug-dave/mm/memory.c 2005-07-28 13:50:37.000000000 -0700 @@ -1640,6 +1640,7 @@ static int do_swap_page(struct mm_struct pte_unmap(page_table); spin_unlock(&mm->page_table_lock); +again: page = lookup_swap_cache(entry); if (!page) { swapin_readahead(entry, address, vma); @@ -1668,6 +1669,12 @@ static int do_swap_page(struct mm_struct mark_page_accessed(page); lock_page(page); + if (!PageSwapCache(page)) { + /* page-migration has occured */ + unlock_page(page); + page_cache_release(page); + goto again; + } /* * Back out if somebody else faulted in this pte while we diff -puN mm/shmem.c~AA-PM-09-migrate-swapcache-validate mm/shmem.c --- memhotplug/mm/shmem.c~AA-PM-09-migrate-swapcache-validate 2005-07-28 13:50:37.000000000 -0700 +++ memhotplug-dave/mm/shmem.c 2005-07-28 13:50:37.000000000 -0700 @@ -1017,6 +1017,14 @@ repeat: page_cache_release(swappage); goto repeat; } + if (!PageSwapCache(swappage)) { + /* page-migration has occured */ + shmem_swp_unmap(entry); + spin_unlock(&info->lock); + unlock_page(swappage); + page_cache_release(swappage); + goto repeat; + } if (PageWriteback(swappage)) { shmem_swp_unmap(entry); spin_unlock(&info->lock); diff -puN mm/swapfile.c~AA-PM-09-migrate-swapcache-validate mm/swapfile.c --- memhotplug/mm/swapfile.c~AA-PM-09-migrate-swapcache-validate 2005-07-28 13:50:37.000000000 -0700 +++ memhotplug-dave/mm/swapfile.c 2005-07-28 13:50:37.000000000 -0700 @@ -618,6 +618,7 @@ static int try_to_unuse(unsigned int typ */ swap_map = &si->swap_map[i]; entry = swp_entry(type, i); +again: page = read_swap_cache_async(entry, NULL, 0); if (!page) { /* @@ -652,6 +653,12 @@ static int try_to_unuse(unsigned int typ wait_on_page_locked(page); wait_on_page_writeback(page); lock_page(page); + if (!PageSwapCache(page)) { + /* page-migration has occured */ + unlock_page(page); + page_cache_release(page); + goto again; + } wait_on_page_writeback(page); /* _