diff options
Diffstat (limited to 'mm/migrate.c')
-rw-r--r-- | mm/migrate.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index c07327487111..b10237d8b459 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -53,14 +53,9 @@ int migrate_prep(void) | |||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | static inline void move_to_lru(struct page *page) | ||
57 | { | ||
58 | lru_cache_add_lru(page, page_lru(page)); | ||
59 | put_page(page); | ||
60 | } | ||
61 | |||
62 | /* | 56 | /* |
63 | * Add isolated pages on the list back to the LRU. | 57 | * Add isolated pages on the list back to the LRU under page lock |
58 | * to avoid leaking evictable pages back onto unevictable list. | ||
64 | * | 59 | * |
65 | * returns the number of pages put back. | 60 | * returns the number of pages put back. |
66 | */ | 61 | */ |
@@ -72,7 +67,7 @@ int putback_lru_pages(struct list_head *l) | |||
72 | 67 | ||
73 | list_for_each_entry_safe(page, page2, l, lru) { | 68 | list_for_each_entry_safe(page, page2, l, lru) { |
74 | list_del(&page->lru); | 69 | list_del(&page->lru); |
75 | move_to_lru(page); | 70 | putback_lru_page(page); |
76 | count++; | 71 | count++; |
77 | } | 72 | } |
78 | return count; | 73 | return count; |
@@ -354,8 +349,11 @@ static void migrate_page_copy(struct page *newpage, struct page *page) | |||
354 | SetPageReferenced(newpage); | 349 | SetPageReferenced(newpage); |
355 | if (PageUptodate(page)) | 350 | if (PageUptodate(page)) |
356 | SetPageUptodate(newpage); | 351 | SetPageUptodate(newpage); |
357 | if (PageActive(page)) | 352 | if (TestClearPageActive(page)) { |
353 | VM_BUG_ON(PageUnevictable(page)); | ||
358 | SetPageActive(newpage); | 354 | SetPageActive(newpage); |
355 | } else | ||
356 | unevictable_migrate_page(newpage, page); | ||
359 | if (PageChecked(page)) | 357 | if (PageChecked(page)) |
360 | SetPageChecked(newpage); | 358 | SetPageChecked(newpage); |
361 | if (PageMappedToDisk(page)) | 359 | if (PageMappedToDisk(page)) |
@@ -376,7 +374,6 @@ static void migrate_page_copy(struct page *newpage, struct page *page) | |||
376 | #ifdef CONFIG_SWAP | 374 | #ifdef CONFIG_SWAP |
377 | ClearPageSwapCache(page); | 375 | ClearPageSwapCache(page); |
378 | #endif | 376 | #endif |
379 | ClearPageActive(page); | ||
380 | ClearPagePrivate(page); | 377 | ClearPagePrivate(page); |
381 | set_page_private(page, 0); | 378 | set_page_private(page, 0); |
382 | page->mapping = NULL; | 379 | page->mapping = NULL; |
@@ -555,6 +552,10 @@ static int fallback_migrate_page(struct address_space *mapping, | |||
555 | * | 552 | * |
556 | * The new page will have replaced the old page if this function | 553 | * The new page will have replaced the old page if this function |
557 | * is successful. | 554 | * is successful. |
555 | * | ||
556 | * Return value: | ||
557 | * < 0 - error code | ||
558 | * == 0 - success | ||
558 | */ | 559 | */ |
559 | static int move_to_new_page(struct page *newpage, struct page *page) | 560 | static int move_to_new_page(struct page *newpage, struct page *page) |
560 | { | 561 | { |
@@ -617,9 +618,10 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, | |||
617 | if (!newpage) | 618 | if (!newpage) |
618 | return -ENOMEM; | 619 | return -ENOMEM; |
619 | 620 | ||
620 | if (page_count(page) == 1) | 621 | if (page_count(page) == 1) { |
621 | /* page was freed from under us. So we are done. */ | 622 | /* page was freed from under us. So we are done. */ |
622 | goto move_newpage; | 623 | goto move_newpage; |
624 | } | ||
623 | 625 | ||
624 | charge = mem_cgroup_prepare_migration(page, newpage); | 626 | charge = mem_cgroup_prepare_migration(page, newpage); |
625 | if (charge == -ENOMEM) { | 627 | if (charge == -ENOMEM) { |
@@ -693,7 +695,6 @@ rcu_unlock: | |||
693 | rcu_read_unlock(); | 695 | rcu_read_unlock(); |
694 | 696 | ||
695 | unlock: | 697 | unlock: |
696 | |||
697 | unlock_page(page); | 698 | unlock_page(page); |
698 | 699 | ||
699 | if (rc != -EAGAIN) { | 700 | if (rc != -EAGAIN) { |
@@ -704,17 +705,19 @@ unlock: | |||
704 | * restored. | 705 | * restored. |
705 | */ | 706 | */ |
706 | list_del(&page->lru); | 707 | list_del(&page->lru); |
707 | move_to_lru(page); | 708 | putback_lru_page(page); |
708 | } | 709 | } |
709 | 710 | ||
710 | move_newpage: | 711 | move_newpage: |
711 | if (!charge) | 712 | if (!charge) |
712 | mem_cgroup_end_migration(newpage); | 713 | mem_cgroup_end_migration(newpage); |
714 | |||
713 | /* | 715 | /* |
714 | * Move the new page to the LRU. If migration was not successful | 716 | * Move the new page to the LRU. If migration was not successful |
715 | * then this will free the page. | 717 | * then this will free the page. |
716 | */ | 718 | */ |
717 | move_to_lru(newpage); | 719 | putback_lru_page(newpage); |
720 | |||
718 | if (result) { | 721 | if (result) { |
719 | if (rc) | 722 | if (rc) |
720 | *result = rc; | 723 | *result = rc; |