

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 <taka@valinux.co.jp>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 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-03-28 16:38:14.000000000 -0800
+++ memhotplug-dave/mm/memory.c	2005-03-28 16:38:14.000000000 -0800
@@ -1577,6 +1577,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);
@@ -1605,6 +1606,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-03-28 16:38:14.000000000 -0800
+++ memhotplug-dave/mm/shmem.c	2005-03-28 16:38:14.000000000 -0800
@@ -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-03-28 16:38:14.000000000 -0800
+++ memhotplug-dave/mm/swapfile.c	2005-03-28 16:38:14.000000000 -0800
@@ -641,6 +641,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) {
 			/*
@@ -675,6 +676,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);
 
 		/*
_
