Commit 03f15c86 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

mm: simplify page migration's anon_vma comment and flow

__unmap_and_move() contains a long stale comment on page_get_anon_vma()
and PageSwapCache(), with an odd control flow that's hard to follow.
Mostly this reflects our confusion about the lifetime of an anon_vma, in
the early days of page migration, before we could take a reference to one.
 Nowadays this seems quite straightforward: cut it all down to essentials.

I cannot see the relevance of swapcache here at all, so don't treat it any
differently: I believe the old comment reflects in part our anon_vma
confusions, and in part the original v2.6.16 page migration technique,
which used actual swap to migrate anon instead of swap-like migration
entries.  Why should a swapcache page not be migrated with the aid of
migration entry ptes like everything else?  So lose that comment now, and
enable migration entries for swapcache in the next patch.
Signed-off-by: default avatarHugh Dickins <hughd@google.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5c3f9a67
...@@ -819,6 +819,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage, ...@@ -819,6 +819,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
goto out_unlock; goto out_unlock;
wait_on_page_writeback(page); wait_on_page_writeback(page);
} }
/* /*
* By try_to_unmap(), page->mapcount goes down to 0 here. In this case, * By try_to_unmap(), page->mapcount goes down to 0 here. In this case,
* we cannot notice that anon_vma is freed while we migrates a page. * we cannot notice that anon_vma is freed while we migrates a page.
...@@ -826,34 +827,15 @@ static int __unmap_and_move(struct page *page, struct page *newpage, ...@@ -826,34 +827,15 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
* of migration. File cache pages are no problem because of page_lock() * of migration. File cache pages are no problem because of page_lock()
* File Caches may use write_page() or lock_page() in migration, then, * File Caches may use write_page() or lock_page() in migration, then,
* just care Anon page here. * just care Anon page here.
*/ *
if (PageAnon(page) && !PageKsm(page)) { * Only page_get_anon_vma() understands the subtleties of
/*
* Only page_lock_anon_vma_read() understands the subtleties of
* getting a hold on an anon_vma from outside one of its mms. * getting a hold on an anon_vma from outside one of its mms.
* But if we cannot get anon_vma, then we won't need it anyway,
* because that implies that the anon page is no longer mapped
* (and cannot be remapped so long as we hold the page lock).
*/ */
if (PageAnon(page) && !PageKsm(page))
anon_vma = page_get_anon_vma(page); anon_vma = page_get_anon_vma(page);
if (anon_vma) {
/*
* Anon page
*/
} else if (PageSwapCache(page)) {
/*
* We cannot be sure that the anon_vma of an unmapped
* swapcache page is safe to use because we don't
* know in advance if the VMA that this page belonged
* to still exists. If the VMA and others sharing the
* data have been freed, then the anon_vma could
* already be invalid.
*
* To avoid this possibility, swapcache pages get
* migrated but are not remapped when migration
* completes
*/
} else {
goto out_unlock;
}
}
/* /*
* Block others from accessing the new page when we get around to * Block others from accessing the new page when we get around to
...@@ -898,6 +880,8 @@ static int __unmap_and_move(struct page *page, struct page *newpage, ...@@ -898,6 +880,8 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
} }
} else if (page_mapped(page)) { } else if (page_mapped(page)) {
/* Establish migration ptes */ /* Establish migration ptes */
VM_BUG_ON_PAGE(PageAnon(page) && !PageKsm(page) && !anon_vma,
page);
try_to_unmap(page, try_to_unmap(page,
TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS); TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
page_was_mapped = 1; page_was_mapped = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment