diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/memory.c | 7 | ||||
-rw-r--r-- | mm/shmem.c | 8 | ||||
-rw-r--r-- | mm/swapfile.c | 7 |
3 files changed, 22 insertions, 0 deletions
diff --git a/mm/memory.c b/mm/memory.c index 7a11ddd5060f..2bee1f21aa8a 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1871,6 +1871,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1871 | goto out; | 1871 | goto out; |
1872 | 1872 | ||
1873 | entry = pte_to_swp_entry(orig_pte); | 1873 | entry = pte_to_swp_entry(orig_pte); |
1874 | again: | ||
1874 | page = lookup_swap_cache(entry); | 1875 | page = lookup_swap_cache(entry); |
1875 | if (!page) { | 1876 | if (!page) { |
1876 | swapin_readahead(entry, address, vma); | 1877 | swapin_readahead(entry, address, vma); |
@@ -1894,6 +1895,12 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma, | |||
1894 | 1895 | ||
1895 | mark_page_accessed(page); | 1896 | mark_page_accessed(page); |
1896 | lock_page(page); | 1897 | lock_page(page); |
1898 | if (!PageSwapCache(page)) { | ||
1899 | /* Page migration has occured */ | ||
1900 | unlock_page(page); | ||
1901 | page_cache_release(page); | ||
1902 | goto again; | ||
1903 | } | ||
1897 | 1904 | ||
1898 | /* | 1905 | /* |
1899 | * Back out if somebody else already faulted in this pte. | 1906 | * Back out if somebody else already faulted in this pte. |
diff --git a/mm/shmem.c b/mm/shmem.c index ce501bce1c2e..f7ac7b812f92 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1028,6 +1028,14 @@ repeat: | |||
1028 | page_cache_release(swappage); | 1028 | page_cache_release(swappage); |
1029 | goto repeat; | 1029 | goto repeat; |
1030 | } | 1030 | } |
1031 | if (!PageSwapCache(swappage)) { | ||
1032 | /* Page migration has occured */ | ||
1033 | shmem_swp_unmap(entry); | ||
1034 | spin_unlock(&info->lock); | ||
1035 | unlock_page(swappage); | ||
1036 | page_cache_release(swappage); | ||
1037 | goto repeat; | ||
1038 | } | ||
1031 | if (PageWriteback(swappage)) { | 1039 | if (PageWriteback(swappage)) { |
1032 | shmem_swp_unmap(entry); | 1040 | shmem_swp_unmap(entry); |
1033 | spin_unlock(&info->lock); | 1041 | spin_unlock(&info->lock); |
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); |
649 | again: | ||
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 | /* |