mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
[PATCH] page migration cleanup: move fallback handling into special function
Move the fallback code into a new fallback function and make the function behave like any other migration function. This requires retaking the lock if pageout() drops it. 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
2d1db3b117
commit
8351a6e478
1 changed files with 39 additions and 51 deletions
90
mm/migrate.c
90
mm/migrate.c
|
@ -349,6 +349,42 @@ int buffer_migrate_page(struct address_space *mapping,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(buffer_migrate_page);
|
EXPORT_SYMBOL(buffer_migrate_page);
|
||||||
|
|
||||||
|
static int fallback_migrate_page(struct address_space *mapping,
|
||||||
|
struct page *newpage, struct page *page)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 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)) {
|
||||||
|
switch (pageout(page, mapping)) {
|
||||||
|
case PAGE_KEEP:
|
||||||
|
case PAGE_ACTIVATE:
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
case PAGE_SUCCESS:
|
||||||
|
/* Relock since we lost the lock */
|
||||||
|
lock_page(page);
|
||||||
|
/* Must retry since page state may have changed */
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
case PAGE_CLEAN:
|
||||||
|
; /* try to migrate the page below */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buffers may be managed in a filesystem specific way.
|
||||||
|
* We must have no buffers or drop them.
|
||||||
|
*/
|
||||||
|
if (page_has_buffers(page) &&
|
||||||
|
!try_to_release_page(page, GFP_KERNEL))
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
return migrate_page(mapping, newpage, page);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* migrate_pages
|
* migrate_pages
|
||||||
*
|
*
|
||||||
|
@ -478,7 +514,7 @@ redo:
|
||||||
if (!mapping)
|
if (!mapping)
|
||||||
goto unlock_both;
|
goto unlock_both;
|
||||||
|
|
||||||
if (mapping->a_ops->migratepage) {
|
if (mapping->a_ops->migratepage)
|
||||||
/*
|
/*
|
||||||
* Most pages have a mapping and most filesystems
|
* Most pages have a mapping and most filesystems
|
||||||
* should provide a migration function. Anonymous
|
* should provide a migration function. Anonymous
|
||||||
|
@ -488,56 +524,8 @@ redo:
|
||||||
*/
|
*/
|
||||||
rc = mapping->a_ops->migratepage(mapping,
|
rc = mapping->a_ops->migratepage(mapping,
|
||||||
newpage, page);
|
newpage, page);
|
||||||
goto unlock_both;
|
else
|
||||||
}
|
rc = fallback_migrate_page(mapping, newpage, page);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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)) {
|
|
||||||
switch (pageout(page, mapping)) {
|
|
||||||
case PAGE_KEEP:
|
|
||||||
case PAGE_ACTIVATE:
|
|
||||||
goto unlock_both;
|
|
||||||
|
|
||||||
case PAGE_SUCCESS:
|
|
||||||
unlock_page(newpage);
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
case PAGE_CLEAN:
|
|
||||||
; /* try to migrate the page below */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Buffers are managed in a filesystem specific way.
|
|
||||||
* We must have no buffers or drop them.
|
|
||||||
*/
|
|
||||||
if (!page_has_buffers(page) ||
|
|
||||||
try_to_release_page(page, GFP_KERNEL)) {
|
|
||||||
rc = migrate_page(mapping, newpage, page);
|
|
||||||
goto unlock_both;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* On early passes with mapped pages simply
|
|
||||||
* retry. There may be a lock held for some
|
|
||||||
* buffers that may go away. Later
|
|
||||||
* swap them out.
|
|
||||||
*/
|
|
||||||
if (pass > 4) {
|
|
||||||
/*
|
|
||||||
* Persistently unable to drop buffers..... As a
|
|
||||||
* measure of last resort we fall back to
|
|
||||||
* swap_page().
|
|
||||||
*/
|
|
||||||
unlock_page(newpage);
|
|
||||||
newpage = NULL;
|
|
||||||
rc = swap_page(page);
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
|
|
||||||
unlock_both:
|
unlock_both:
|
||||||
unlock_page(newpage);
|
unlock_page(newpage);
|
||||||
|
|
Loading…
Reference in a new issue