diff options
Diffstat (limited to 'mm/migrate.c')
-rw-r--r-- | mm/migrate.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index 6a207e8d17ea..857a987e3690 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -115,11 +115,6 @@ int putback_lru_pages(struct list_head *l) | |||
115 | return count; | 115 | return count; |
116 | } | 116 | } |
117 | 117 | ||
118 | static inline int is_swap_pte(pte_t pte) | ||
119 | { | ||
120 | return !pte_none(pte) && !pte_present(pte) && !pte_file(pte); | ||
121 | } | ||
122 | |||
123 | /* | 118 | /* |
124 | * Restore a potential migration pte to a working pte entry | 119 | * Restore a potential migration pte to a working pte entry |
125 | */ | 120 | */ |
@@ -645,15 +640,33 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, | |||
645 | rcu_read_lock(); | 640 | rcu_read_lock(); |
646 | rcu_locked = 1; | 641 | rcu_locked = 1; |
647 | } | 642 | } |
643 | |||
648 | /* | 644 | /* |
649 | * This is a corner case handling. | 645 | * Corner case handling: |
650 | * 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 |
651 | * and treated as swapcache but has no rmap yet. | 647 | * and treated as swapcache but it has no rmap yet. |
652 | * Calling try_to_unmap() against a page->mapping==NULL page is | 648 | * Calling try_to_unmap() against a page->mapping==NULL page will |
653 | * 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. | ||
654 | */ | 655 | */ |
655 | 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 | } | ||
656 | goto rcu_unlock; | 667 | goto rcu_unlock; |
668 | } | ||
669 | |||
657 | /* Establish migration ptes or remove ptes */ | 670 | /* Establish migration ptes or remove ptes */ |
658 | try_to_unmap(page, 1); | 671 | try_to_unmap(page, 1); |
659 | 672 | ||