Commit 418aade4 authored by Christoph Lameter's avatar Christoph Lameter Committed by Linus Torvalds

[PATCH] Updates for page migration

This adds some additional comments in order to help others figure out how
exactly the code works.  And fix a variable name.

Also swap_page does need to ignore all reference bits when unmapping a
page.  Otherwise we may have to repeatedly unmap a frequently touched page.
So change the try_to_unmap parameter to 1.
Signed-off-by: default avatarChristoph Lameter <clameter@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8977d929
...@@ -632,7 +632,7 @@ static int swap_page(struct page *page) ...@@ -632,7 +632,7 @@ static int swap_page(struct page *page)
struct address_space *mapping = page_mapping(page); struct address_space *mapping = page_mapping(page);
if (page_mapped(page) && mapping) if (page_mapped(page) && mapping)
if (try_to_unmap(page, 0) != SWAP_SUCCESS) if (try_to_unmap(page, 1) != SWAP_SUCCESS)
goto unlock_retry; goto unlock_retry;
if (PageDirty(page)) { if (PageDirty(page)) {
...@@ -839,7 +839,7 @@ EXPORT_SYMBOL(migrate_page); ...@@ -839,7 +839,7 @@ EXPORT_SYMBOL(migrate_page);
* pages are swapped out. * pages are swapped out.
* *
* The function returns after 10 attempts or if no pages * The function returns after 10 attempts or if no pages
* are movable anymore because t has become empty * are movable anymore because to has become empty
* or no retryable pages exist anymore. * or no retryable pages exist anymore.
* *
* Return: Number of pages not migrated when "to" ran empty. * Return: Number of pages not migrated when "to" ran empty.
...@@ -928,12 +928,21 @@ int migrate_pages(struct list_head *from, struct list_head *to, ...@@ -928,12 +928,21 @@ int migrate_pages(struct list_head *from, struct list_head *to,
goto unlock_both; goto unlock_both;
if (mapping->a_ops->migratepage) { if (mapping->a_ops->migratepage) {
/*
* Most pages have a mapping and most filesystems
* should provide a migration function. Anonymous
* pages are part of swap space which also has its
* own migration function. This is the most common
* path for page migration.
*/
rc = mapping->a_ops->migratepage(newpage, page); rc = mapping->a_ops->migratepage(newpage, page);
goto unlock_both; goto unlock_both;
} }
/* /*
* Trigger writeout if page is dirty * Default handling if a filesystem does not provide
* a migration function. We can only migrate clean
* pages so try to write out any dirty pages first.
*/ */
if (PageDirty(page)) { if (PageDirty(page)) {
switch (pageout(page, mapping)) { switch (pageout(page, mapping)) {
...@@ -949,9 +958,10 @@ int migrate_pages(struct list_head *from, struct list_head *to, ...@@ -949,9 +958,10 @@ int migrate_pages(struct list_head *from, struct list_head *to,
; /* try to migrate the page below */ ; /* try to migrate the page below */
} }
} }
/* /*
* If we have no buffer or can release the buffer * Buffers are managed in a filesystem specific way.
* then do a simple migration. * We must have no buffers or drop them.
*/ */
if (!page_has_buffers(page) || if (!page_has_buffers(page) ||
try_to_release_page(page, GFP_KERNEL)) { try_to_release_page(page, GFP_KERNEL)) {
...@@ -966,6 +976,11 @@ int migrate_pages(struct list_head *from, struct list_head *to, ...@@ -966,6 +976,11 @@ int migrate_pages(struct list_head *from, struct list_head *to,
* swap them out. * swap them out.
*/ */
if (pass > 4) { if (pass > 4) {
/*
* Persistently unable to drop buffers..... As a
* measure of last resort we fall back to
* swap_page().
*/
unlock_page(newpage); unlock_page(newpage);
newpage = NULL; newpage = NULL;
rc = swap_page(page); rc = swap_page(page);
......
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