[PATCH] page migration: fail if page is in a vma flagged VM_LOCKED
page migration currently simply retries a couple of times if try_to_unmap() fails without inspecting the return code. However, SWAP_FAIL indicates that the page is in a vma that has the VM_LOCKED flag set (if ignore_refs ==1). We can check for that return code and avoid retrying the migration. migrate_page_remove_references() now needs to return a reason why the failure occured. So switch migrate_page_remove_references to use -Exx style error messages. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
e843e280cb
commit
4983da07f1
|
@ -3060,6 +3060,7 @@ int buffer_migrate_page(struct page *newpage, struct page *page)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = page->mapping;
|
struct address_space *mapping = page->mapping;
|
||||||
struct buffer_head *bh, *head;
|
struct buffer_head *bh, *head;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (!mapping)
|
if (!mapping)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
@ -3069,8 +3070,9 @@ int buffer_migrate_page(struct page *newpage, struct page *page)
|
||||||
|
|
||||||
head = page_buffers(page);
|
head = page_buffers(page);
|
||||||
|
|
||||||
if (migrate_page_remove_references(newpage, page, 3))
|
rc = migrate_page_remove_references(newpage, page, 3);
|
||||||
return -EAGAIN;
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
bh = head;
|
bh = head;
|
||||||
do {
|
do {
|
||||||
|
|
18
mm/vmscan.c
18
mm/vmscan.c
|
@ -700,7 +700,7 @@ int migrate_page_remove_references(struct page *newpage,
|
||||||
* the page.
|
* the page.
|
||||||
*/
|
*/
|
||||||
if (!mapping || page_mapcount(page) + nr_refs != page_count(page))
|
if (!mapping || page_mapcount(page) + nr_refs != page_count(page))
|
||||||
return 1;
|
return -EAGAIN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Establish swap ptes for anonymous pages or destroy pte
|
* Establish swap ptes for anonymous pages or destroy pte
|
||||||
|
@ -721,13 +721,15 @@ int migrate_page_remove_references(struct page *newpage,
|
||||||
* If the page was not migrated then the PageSwapCache bit
|
* If the page was not migrated then the PageSwapCache bit
|
||||||
* is still set and the operation may continue.
|
* is still set and the operation may continue.
|
||||||
*/
|
*/
|
||||||
try_to_unmap(page, 1);
|
if (try_to_unmap(page, 1) == SWAP_FAIL)
|
||||||
|
/* A vma has VM_LOCKED set -> Permanent failure */
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Give up if we were unable to remove all mappings.
|
* Give up if we were unable to remove all mappings.
|
||||||
*/
|
*/
|
||||||
if (page_mapcount(page))
|
if (page_mapcount(page))
|
||||||
return 1;
|
return -EAGAIN;
|
||||||
|
|
||||||
write_lock_irq(&mapping->tree_lock);
|
write_lock_irq(&mapping->tree_lock);
|
||||||
|
|
||||||
|
@ -738,7 +740,7 @@ int migrate_page_remove_references(struct page *newpage,
|
||||||
if (!page_mapping(page) || page_count(page) != nr_refs ||
|
if (!page_mapping(page) || page_count(page) != nr_refs ||
|
||||||
*radix_pointer != page) {
|
*radix_pointer != page) {
|
||||||
write_unlock_irq(&mapping->tree_lock);
|
write_unlock_irq(&mapping->tree_lock);
|
||||||
return 1;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -813,10 +815,14 @@ EXPORT_SYMBOL(migrate_page_copy);
|
||||||
*/
|
*/
|
||||||
int migrate_page(struct page *newpage, struct page *page)
|
int migrate_page(struct page *newpage, struct page *page)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
BUG_ON(PageWriteback(page)); /* Writeback must be complete */
|
BUG_ON(PageWriteback(page)); /* Writeback must be complete */
|
||||||
|
|
||||||
if (migrate_page_remove_references(newpage, page, 2))
|
rc = migrate_page_remove_references(newpage, page, 2);
|
||||||
return -EAGAIN;
|
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
migrate_page_copy(newpage, page);
|
migrate_page_copy(newpage, page);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue