From d0c338ed0e5d3d57a95b677113bae2e36b5efe3e Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 4 Feb 2008 22:29:33 -0800 Subject: [PATCH] --- yaml --- r: 83101 b: refs/heads/master c: 62e1c55300f306e06478f460a7eefba085206e0b h: refs/heads/master i: 83099: babe53b11312e1aa8dc135bcbdb40043aada10fe v: v3 --- [refs] | 2 +- trunk/mm/migrate.c | 30 ++++++++++++++++++++++++------ trunk/mm/truncate.c | 2 +- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index 0c4fefe7d2c1..b881a261ee0d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7786fa9ac5366214fb942a9e62c6e46b4272c22c +refs/heads/master: 62e1c55300f306e06478f460a7eefba085206e0b diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 4ee4ccacf986..857a987e3690 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -640,15 +640,33 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, rcu_read_lock(); rcu_locked = 1; } + /* - * This is a corner case handling. - * When a new swap-cache is read into, it is linked to LRU - * and treated as swapcache but has no rmap yet. - * Calling try_to_unmap() against a page->mapping==NULL page is - * BUG. So handle it here. + * Corner case handling: + * 1. When a new swap-cache page is read into, it is added to the LRU + * and treated as swapcache but it has no rmap yet. + * Calling try_to_unmap() against a page->mapping==NULL page will + * trigger a BUG. So handle it here. + * 2. An orphaned page (see truncate_complete_page) might have + * fs-private metadata. The page can be picked up due to memory + * offlining. Everywhere else except page reclaim, the page is + * invisible to the vm, so the page can not be migrated. So try to + * free the metadata, so the page can be freed. */ - if (!page->mapping) + if (!page->mapping) { + if (!PageAnon(page) && PagePrivate(page)) { + /* + * Go direct to try_to_free_buffers() here because + * a) that's what try_to_release_page() would do anyway + * b) we may be under rcu_read_lock() here, so we can't + * use GFP_KERNEL which is what try_to_release_page() + * needs to be effective. + */ + try_to_free_buffers(page); + } goto rcu_unlock; + } + /* Establish migration ptes or remove ptes */ try_to_unmap(page, 1); diff --git a/trunk/mm/truncate.c b/trunk/mm/truncate.c index 9838c050e2dd..c35c49e54fb6 100644 --- a/trunk/mm/truncate.c +++ b/trunk/mm/truncate.c @@ -84,7 +84,7 @@ EXPORT_SYMBOL(cancel_dirty_page); /* * If truncate cannot remove the fs-private metadata from the page, the page - * becomes anonymous. It will be left on the LRU and may even be mapped into + * becomes orphaned. It will be left on the LRU and may even be mapped into * user pagetables if we're racing with filemap_fault(). * * We need to bale out if page->mapping is no longer equal to the original