aboutsummaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index 4ee4ccacf986..857a987e3690 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -640,15 +640,33 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
640 rcu_read_lock(); 640 rcu_read_lock();
641 rcu_locked = 1; 641 rcu_locked = 1;
642 } 642 }
643
643 /* 644 /*
644 * This is a corner case handling. 645 * Corner case handling:
645 * When a new swap-cache is read into, it is linked to LRU 646 * 1. When a new swap-cache page is read into, it is added to the LRU
646 * and treated as swapcache but has no rmap yet. 647 * and treated as swapcache but it has no rmap yet.
647 * Calling try_to_unmap() against a page->mapping==NULL page is 648 * Calling try_to_unmap() against a page->mapping==NULL page will
648 * BUG. So handle it here. 649 * trigger a BUG. So handle it here.
650 * 2. An orphaned page (see truncate_complete_page) might have
651 * fs-private metadata. The page can be picked up due to memory
652 * offlining. Everywhere else except page reclaim, the page is
653 * invisible to the vm, so the page can not be migrated. So try to
654 * free the metadata, so the page can be freed.
649 */ 655 */
650 if (!page->mapping) 656 if (!page->mapping) {
657 if (!PageAnon(page) && PagePrivate(page)) {
658 /*
659 * Go direct to try_to_free_buffers() here because
660 * a) that's what try_to_release_page() would do anyway
661 * b) we may be under rcu_read_lock() here, so we can't
662 * use GFP_KERNEL which is what try_to_release_page()
663 * needs to be effective.
664 */
665 try_to_free_buffers(page);
666 }
651 goto rcu_unlock; 667 goto rcu_unlock;
668 }
669
652 /* Establish migration ptes or remove ptes */ 670 /* Establish migration ptes or remove ptes */
653 try_to_unmap(page, 1); 671 try_to_unmap(page, 1);
654 672