aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2006-02-01 06:05:36 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-02-01 11:53:16 -0500
commitb16664e44c54525be89dc07ad15a13b4eeec5634 (patch)
tree1844d193009c1e55e3c26256feb14bc622ec9af3 /mm/swapfile.c
parent2a16e3f4b0c408b9e50297d2ec27e295d490267a (diff)
[PATCH] Direct Migration V9: PageSwapCache checks
Check for PageSwapCache after looking up and locking a swap page. The page migration code may change a swap pte to point to a different page under lock_page(). If that happens then the vm must retry the lookup operation in the swap space to find the correct page number. There are a couple of locations in the VM where a lock_page() is done on a swap page. In these locations we need to check afterwards if the page was migrated. If the page was migrated then the old page that was looked up before was freed and no longer has the PageSwapCache bit set. Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp> Signed-off-by: Dave Hansen <haveblue@us.ibm.com> Signed-off-by: Christoph Lameter <clameter@@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r--mm/swapfile.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index f1e69c30d203..9678182e0eef 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -646,6 +646,7 @@ static int try_to_unuse(unsigned int type)
646 */ 646 */
647 swap_map = &si->swap_map[i]; 647 swap_map = &si->swap_map[i];
648 entry = swp_entry(type, i); 648 entry = swp_entry(type, i);
649again:
649 page = read_swap_cache_async(entry, NULL, 0); 650 page = read_swap_cache_async(entry, NULL, 0);
650 if (!page) { 651 if (!page) {
651 /* 652 /*
@@ -680,6 +681,12 @@ static int try_to_unuse(unsigned int type)
680 wait_on_page_locked(page); 681 wait_on_page_locked(page);
681 wait_on_page_writeback(page); 682 wait_on_page_writeback(page);
682 lock_page(page); 683 lock_page(page);
684 if (!PageSwapCache(page)) {
685 /* Page migration has occured */
686 unlock_page(page);
687 page_cache_release(page);
688 goto again;
689 }
683 wait_on_page_writeback(page); 690 wait_on_page_writeback(page);
684 691
685 /* 692 /*