diff options
Diffstat (limited to 'mm/memory-failure.c')
-rw-r--r-- | mm/memory-failure.c | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 27f7210e7fab..73066b80d14a 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -220,6 +220,9 @@ static int kill_proc(struct task_struct *t, unsigned long addr, int trapno, | |||
220 | */ | 220 | */ |
221 | void shake_page(struct page *p, int access) | 221 | void shake_page(struct page *p, int access) |
222 | { | 222 | { |
223 | if (PageHuge(p)) | ||
224 | return; | ||
225 | |||
223 | if (!PageSlab(p)) { | 226 | if (!PageSlab(p)) { |
224 | lru_add_drain_all(); | 227 | lru_add_drain_all(); |
225 | if (PageLRU(p)) | 228 | if (PageLRU(p)) |
@@ -322,7 +325,7 @@ static void add_to_kill(struct task_struct *tsk, struct page *p, | |||
322 | * wrong earlier. | 325 | * wrong earlier. |
323 | */ | 326 | */ |
324 | static void kill_procs(struct list_head *to_kill, int forcekill, int trapno, | 327 | static void kill_procs(struct list_head *to_kill, int forcekill, int trapno, |
325 | int fail, struct page *page, unsigned long pfn, | 328 | bool fail, struct page *page, unsigned long pfn, |
326 | int flags) | 329 | int flags) |
327 | { | 330 | { |
328 | struct to_kill *tk, *next; | 331 | struct to_kill *tk, *next; |
@@ -904,35 +907,36 @@ EXPORT_SYMBOL_GPL(get_hwpoison_page); | |||
904 | * Do all that is necessary to remove user space mappings. Unmap | 907 | * Do all that is necessary to remove user space mappings. Unmap |
905 | * the pages and send SIGBUS to the processes if the data was dirty. | 908 | * the pages and send SIGBUS to the processes if the data was dirty. |
906 | */ | 909 | */ |
907 | static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | 910 | static bool hwpoison_user_mappings(struct page *p, unsigned long pfn, |
908 | int trapno, int flags, struct page **hpagep) | 911 | int trapno, int flags, struct page **hpagep) |
909 | { | 912 | { |
910 | enum ttu_flags ttu = TTU_UNMAP | TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS; | 913 | enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_IGNORE_ACCESS; |
911 | struct address_space *mapping; | 914 | struct address_space *mapping; |
912 | LIST_HEAD(tokill); | 915 | LIST_HEAD(tokill); |
913 | int ret; | 916 | bool unmap_success; |
914 | int kill = 1, forcekill; | 917 | int kill = 1, forcekill; |
915 | struct page *hpage = *hpagep; | 918 | struct page *hpage = *hpagep; |
919 | bool mlocked = PageMlocked(hpage); | ||
916 | 920 | ||
917 | /* | 921 | /* |
918 | * Here we are interested only in user-mapped pages, so skip any | 922 | * Here we are interested only in user-mapped pages, so skip any |
919 | * other types of pages. | 923 | * other types of pages. |
920 | */ | 924 | */ |
921 | if (PageReserved(p) || PageSlab(p)) | 925 | if (PageReserved(p) || PageSlab(p)) |
922 | return SWAP_SUCCESS; | 926 | return true; |
923 | if (!(PageLRU(hpage) || PageHuge(p))) | 927 | if (!(PageLRU(hpage) || PageHuge(p))) |
924 | return SWAP_SUCCESS; | 928 | return true; |
925 | 929 | ||
926 | /* | 930 | /* |
927 | * This check implies we don't kill processes if their pages | 931 | * This check implies we don't kill processes if their pages |
928 | * are in the swap cache early. Those are always late kills. | 932 | * are in the swap cache early. Those are always late kills. |
929 | */ | 933 | */ |
930 | if (!page_mapped(hpage)) | 934 | if (!page_mapped(hpage)) |
931 | return SWAP_SUCCESS; | 935 | return true; |
932 | 936 | ||
933 | if (PageKsm(p)) { | 937 | if (PageKsm(p)) { |
934 | pr_err("Memory failure: %#lx: can't handle KSM pages.\n", pfn); | 938 | pr_err("Memory failure: %#lx: can't handle KSM pages.\n", pfn); |
935 | return SWAP_FAIL; | 939 | return false; |
936 | } | 940 | } |
937 | 941 | ||
938 | if (PageSwapCache(p)) { | 942 | if (PageSwapCache(p)) { |
@@ -971,12 +975,19 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
971 | if (kill) | 975 | if (kill) |
972 | collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); | 976 | collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); |
973 | 977 | ||
974 | ret = try_to_unmap(hpage, ttu); | 978 | unmap_success = try_to_unmap(hpage, ttu); |
975 | if (ret != SWAP_SUCCESS) | 979 | if (!unmap_success) |
976 | pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n", | 980 | pr_err("Memory failure: %#lx: failed to unmap page (mapcount=%d)\n", |
977 | pfn, page_mapcount(hpage)); | 981 | pfn, page_mapcount(hpage)); |
978 | 982 | ||
979 | /* | 983 | /* |
984 | * try_to_unmap() might put mlocked page in lru cache, so call | ||
985 | * shake_page() again to ensure that it's flushed. | ||
986 | */ | ||
987 | if (mlocked) | ||
988 | shake_page(hpage, 0); | ||
989 | |||
990 | /* | ||
980 | * Now that the dirty bit has been propagated to the | 991 | * Now that the dirty bit has been propagated to the |
981 | * struct page and all unmaps done we can decide if | 992 | * struct page and all unmaps done we can decide if |
982 | * killing is needed or not. Only kill when the page | 993 | * killing is needed or not. Only kill when the page |
@@ -987,10 +998,9 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
987 | * any accesses to the poisoned memory. | 998 | * any accesses to the poisoned memory. |
988 | */ | 999 | */ |
989 | forcekill = PageDirty(hpage) || (flags & MF_MUST_KILL); | 1000 | forcekill = PageDirty(hpage) || (flags & MF_MUST_KILL); |
990 | kill_procs(&tokill, forcekill, trapno, | 1001 | kill_procs(&tokill, forcekill, trapno, !unmap_success, p, pfn, flags); |
991 | ret != SWAP_SUCCESS, p, pfn, flags); | ||
992 | 1002 | ||
993 | return ret; | 1003 | return unmap_success; |
994 | } | 1004 | } |
995 | 1005 | ||
996 | static void set_page_hwpoison_huge_page(struct page *hpage) | 1006 | static void set_page_hwpoison_huge_page(struct page *hpage) |
@@ -1138,22 +1148,14 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1138 | * The check (unnecessarily) ignores LRU pages being isolated and | 1148 | * The check (unnecessarily) ignores LRU pages being isolated and |
1139 | * walked by the page reclaim code, however that's not a big loss. | 1149 | * walked by the page reclaim code, however that's not a big loss. |
1140 | */ | 1150 | */ |
1141 | if (!PageHuge(p)) { | 1151 | shake_page(p, 0); |
1142 | if (!PageLRU(p)) | 1152 | /* shake_page could have turned it free. */ |
1143 | shake_page(p, 0); | 1153 | if (!PageLRU(p) && is_free_buddy_page(p)) { |
1144 | if (!PageLRU(p)) { | 1154 | if (flags & MF_COUNT_INCREASED) |
1145 | /* | 1155 | action_result(pfn, MF_MSG_BUDDY, MF_DELAYED); |
1146 | * shake_page could have turned it free. | 1156 | else |
1147 | */ | 1157 | action_result(pfn, MF_MSG_BUDDY_2ND, MF_DELAYED); |
1148 | if (is_free_buddy_page(p)) { | 1158 | return 0; |
1149 | if (flags & MF_COUNT_INCREASED) | ||
1150 | action_result(pfn, MF_MSG_BUDDY, MF_DELAYED); | ||
1151 | else | ||
1152 | action_result(pfn, MF_MSG_BUDDY_2ND, | ||
1153 | MF_DELAYED); | ||
1154 | return 0; | ||
1155 | } | ||
1156 | } | ||
1157 | } | 1159 | } |
1158 | 1160 | ||
1159 | lock_page(hpage); | 1161 | lock_page(hpage); |
@@ -1230,8 +1232,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1230 | * When the raw error page is thp tail page, hpage points to the raw | 1232 | * When the raw error page is thp tail page, hpage points to the raw |
1231 | * page after thp split. | 1233 | * page after thp split. |
1232 | */ | 1234 | */ |
1233 | if (hwpoison_user_mappings(p, pfn, trapno, flags, &hpage) | 1235 | if (!hwpoison_user_mappings(p, pfn, trapno, flags, &hpage)) { |
1234 | != SWAP_SUCCESS) { | ||
1235 | action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED); | 1236 | action_result(pfn, MF_MSG_UNMAP_FAILED, MF_IGNORED); |
1236 | res = -EBUSY; | 1237 | res = -EBUSY; |
1237 | goto out; | 1238 | goto out; |
@@ -1543,8 +1544,8 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags) | |||
1543 | if (ret == 1 && !PageLRU(page)) { | 1544 | if (ret == 1 && !PageLRU(page)) { |
1544 | /* Drop page reference which is from __get_any_page() */ | 1545 | /* Drop page reference which is from __get_any_page() */ |
1545 | put_hwpoison_page(page); | 1546 | put_hwpoison_page(page); |
1546 | pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", | 1547 | pr_info("soft_offline: %#lx: unknown non LRU page type %lx (%pGp)\n", |
1547 | pfn, page->flags); | 1548 | pfn, page->flags, &page->flags); |
1548 | return -EIO; | 1549 | return -EIO; |
1549 | } | 1550 | } |
1550 | } | 1551 | } |
@@ -1585,8 +1586,8 @@ static int soft_offline_huge_page(struct page *page, int flags) | |||
1585 | ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, | 1586 | ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, |
1586 | MIGRATE_SYNC, MR_MEMORY_FAILURE); | 1587 | MIGRATE_SYNC, MR_MEMORY_FAILURE); |
1587 | if (ret) { | 1588 | if (ret) { |
1588 | pr_info("soft offline: %#lx: migration failed %d, type %lx\n", | 1589 | pr_info("soft offline: %#lx: migration failed %d, type %lx (%pGp)\n", |
1589 | pfn, ret, page->flags); | 1590 | pfn, ret, page->flags, &page->flags); |
1590 | /* | 1591 | /* |
1591 | * We know that soft_offline_huge_page() tries to migrate | 1592 | * We know that soft_offline_huge_page() tries to migrate |
1592 | * only one hugepage pointed to by hpage, so we need not | 1593 | * only one hugepage pointed to by hpage, so we need not |
@@ -1677,14 +1678,14 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1677 | if (!list_empty(&pagelist)) | 1678 | if (!list_empty(&pagelist)) |
1678 | putback_movable_pages(&pagelist); | 1679 | putback_movable_pages(&pagelist); |
1679 | 1680 | ||
1680 | pr_info("soft offline: %#lx: migration failed %d, type %lx\n", | 1681 | pr_info("soft offline: %#lx: migration failed %d, type %lx (%pGp)\n", |
1681 | pfn, ret, page->flags); | 1682 | pfn, ret, page->flags, &page->flags); |
1682 | if (ret > 0) | 1683 | if (ret > 0) |
1683 | ret = -EIO; | 1684 | ret = -EIO; |
1684 | } | 1685 | } |
1685 | } else { | 1686 | } else { |
1686 | pr_info("soft offline: %#lx: isolation failed: %d, page count %d, type %lx\n", | 1687 | pr_info("soft offline: %#lx: isolation failed: %d, page count %d, type %lx (%pGp)\n", |
1687 | pfn, ret, page_count(page), page->flags); | 1688 | pfn, ret, page_count(page), page->flags, &page->flags); |
1688 | } | 1689 | } |
1689 | return ret; | 1690 | return ret; |
1690 | } | 1691 | } |