From: Mel Gorman on
PageAnon pages that are unmapped may or may not have an anon_vma so
are not currently migrated. However, a swap cache page can be migrated
and fits this description. This patch identifies page swap caches and
allows them to be migrated.

Signed-off-by: Mel Gorman <mel(a)csn.ul.ie>
---
mm/migrate.c | 15 ++++++++++-----
mm/rmap.c | 6 ++++--
2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/mm/migrate.c b/mm/migrate.c
index 35aad2a..f9bf37e 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -203,6 +203,9 @@ static int migrate_page_move_mapping(struct address_space *mapping,
void **pslot;

if (!mapping) {
+ if (PageSwapCache(page))
+ SetPageSwapCache(newpage);
+
/* Anonymous page without mapping */
if (page_count(page) != 1)
return -EAGAIN;
@@ -607,11 +610,13 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
* the page was isolated and when we reached here while
* the RCU lock was not held
*/
- if (!page_mapped(page))
- goto rcu_unlock;
-
- anon_vma = page_anon_vma(page);
- atomic_inc(&anon_vma->external_refcount);
+ if (!page_mapped(page)) {
+ if (!PageSwapCache(page))
+ goto rcu_unlock;
+ } else {
+ anon_vma = page_anon_vma(page);
+ atomic_inc(&anon_vma->external_refcount);
+ }
}

/*
diff --git a/mm/rmap.c b/mm/rmap.c
index af35b75..d5ea1f2 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1394,9 +1394,11 @@ int rmap_walk(struct page *page, int (*rmap_one)(struct page *,

if (unlikely(PageKsm(page)))
return rmap_walk_ksm(page, rmap_one, arg);
- else if (PageAnon(page))
+ else if (PageAnon(page)) {
+ if (PageSwapCache(page))
+ return SWAP_AGAIN;
return rmap_walk_anon(page, rmap_one, arg);
- else
+ } else
return rmap_walk_file(page, rmap_one, arg);
}
#endif /* CONFIG_MIGRATION */
--
1.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/