aboutsummaryrefslogtreecommitdiffstats
path: root/mm/migrate.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/migrate.c')
-rw-r--r--mm/migrate.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/mm/migrate.c b/mm/migrate.c
index bd3fdc202e8b..c74412b381ff 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -915,6 +915,19 @@ out_unlock:
915 put_anon_vma(anon_vma); 915 put_anon_vma(anon_vma);
916 unlock_page(page); 916 unlock_page(page);
917out: 917out:
918 /*
919 * If migration is successful, decrease refcount of the newpage
920 * which will not free the page because new page owner increased
921 * refcounter. As well, if it is LRU page, add the page to LRU
922 * list in here.
923 */
924 if (rc == MIGRATEPAGE_SUCCESS) {
925 if (unlikely(__is_movable_balloon_page(newpage)))
926 put_page(newpage);
927 else
928 putback_lru_page(newpage);
929 }
930
918 return rc; 931 return rc;
919} 932}
920 933
@@ -948,6 +961,12 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
948 961
949 if (page_count(page) == 1) { 962 if (page_count(page) == 1) {
950 /* page was freed from under us. So we are done. */ 963 /* page was freed from under us. So we are done. */
964 ClearPageActive(page);
965 ClearPageUnevictable(page);
966 if (put_new_page)
967 put_new_page(newpage, private);
968 else
969 put_page(newpage);
951 goto out; 970 goto out;
952 } 971 }
953 972
@@ -960,10 +979,8 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page,
960 } 979 }
961 980
962 rc = __unmap_and_move(page, newpage, force, mode); 981 rc = __unmap_and_move(page, newpage, force, mode);
963 if (rc == MIGRATEPAGE_SUCCESS) { 982 if (rc == MIGRATEPAGE_SUCCESS)
964 put_new_page = NULL;
965 set_page_owner_migrate_reason(newpage, reason); 983 set_page_owner_migrate_reason(newpage, reason);
966 }
967 984
968out: 985out:
969 if (rc != -EAGAIN) { 986 if (rc != -EAGAIN) {
@@ -976,34 +993,33 @@ out:
976 list_del(&page->lru); 993 list_del(&page->lru);
977 dec_zone_page_state(page, NR_ISOLATED_ANON + 994 dec_zone_page_state(page, NR_ISOLATED_ANON +
978 page_is_file_cache(page)); 995 page_is_file_cache(page));
979 /* Soft-offlined page shouldn't go through lru cache list */ 996 }
980 if (reason == MR_MEMORY_FAILURE && rc == MIGRATEPAGE_SUCCESS) { 997
998 /*
999 * If migration is successful, releases reference grabbed during
1000 * isolation. Otherwise, restore the page to right list unless
1001 * we want to retry.
1002 */
1003 if (rc == MIGRATEPAGE_SUCCESS) {
1004 put_page(page);
1005 if (reason == MR_MEMORY_FAILURE) {
981 /* 1006 /*
982 * With this release, we free successfully migrated 1007 * Set PG_HWPoison on just freed page
983 * page and set PG_HWPoison on just freed page 1008 * intentionally. Although it's rather weird,
984 * intentionally. Although it's rather weird, it's how 1009 * it's how HWPoison flag works at the moment.
985 * HWPoison flag works at the moment.
986 */ 1010 */
987 put_page(page);
988 if (!test_set_page_hwpoison(page)) 1011 if (!test_set_page_hwpoison(page))
989 num_poisoned_pages_inc(); 1012 num_poisoned_pages_inc();
990 } else 1013 }
1014 } else {
1015 if (rc != -EAGAIN)
991 putback_lru_page(page); 1016 putback_lru_page(page);
1017 if (put_new_page)
1018 put_new_page(newpage, private);
1019 else
1020 put_page(newpage);
992 } 1021 }
993 1022
994 /*
995 * If migration was not successful and there's a freeing callback, use
996 * it. Otherwise, putback_lru_page() will drop the reference grabbed
997 * during isolation.
998 */
999 if (put_new_page)
1000 put_new_page(newpage, private);
1001 else if (unlikely(__is_movable_balloon_page(newpage))) {
1002 /* drop our reference, page already in the balloon */
1003 put_page(newpage);
1004 } else
1005 putback_lru_page(newpage);
1006
1007 if (result) { 1023 if (result) {
1008 if (rc) 1024 if (rc)
1009 *result = rc; 1025 *result = rc;