diff options
-rw-r--r-- | mm/memory-failure.c | 88 |
1 files changed, 25 insertions, 63 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 8e71b6e641ad..17a8e3bc3b01 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -928,7 +928,6 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
928 | int ret; | 928 | int ret; |
929 | int kill = 1, forcekill; | 929 | int kill = 1, forcekill; |
930 | struct page *hpage = *hpagep; | 930 | struct page *hpage = *hpagep; |
931 | struct page *ppage; | ||
932 | 931 | ||
933 | /* | 932 | /* |
934 | * Here we are interested only in user-mapped pages, so skip any | 933 | * Here we are interested only in user-mapped pages, so skip any |
@@ -978,59 +977,6 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
978 | } | 977 | } |
979 | 978 | ||
980 | /* | 979 | /* |
981 | * ppage: poisoned page | ||
982 | * if p is regular page(4k page) | ||
983 | * ppage == real poisoned page; | ||
984 | * else p is hugetlb or THP, ppage == head page. | ||
985 | */ | ||
986 | ppage = hpage; | ||
987 | |||
988 | if (PageTransHuge(hpage)) { | ||
989 | /* | ||
990 | * Verify that this isn't a hugetlbfs head page, the check for | ||
991 | * PageAnon is just for avoid tripping a split_huge_page | ||
992 | * internal debug check, as split_huge_page refuses to deal with | ||
993 | * anything that isn't an anon page. PageAnon can't go away fro | ||
994 | * under us because we hold a refcount on the hpage, without a | ||
995 | * refcount on the hpage. split_huge_page can't be safely called | ||
996 | * in the first place, having a refcount on the tail isn't | ||
997 | * enough * to be safe. | ||
998 | */ | ||
999 | if (!PageHuge(hpage) && PageAnon(hpage)) { | ||
1000 | if (unlikely(split_huge_page(hpage))) { | ||
1001 | /* | ||
1002 | * FIXME: if splitting THP is failed, it is | ||
1003 | * better to stop the following operation rather | ||
1004 | * than causing panic by unmapping. System might | ||
1005 | * survive if the page is freed later. | ||
1006 | */ | ||
1007 | printk(KERN_INFO | ||
1008 | "MCE %#lx: failed to split THP\n", pfn); | ||
1009 | |||
1010 | BUG_ON(!PageHWPoison(p)); | ||
1011 | return SWAP_FAIL; | ||
1012 | } | ||
1013 | /* | ||
1014 | * We pinned the head page for hwpoison handling, | ||
1015 | * now we split the thp and we are interested in | ||
1016 | * the hwpoisoned raw page, so move the refcount | ||
1017 | * to it. Similarly, page lock is shifted. | ||
1018 | */ | ||
1019 | if (hpage != p) { | ||
1020 | if (!(flags & MF_COUNT_INCREASED)) { | ||
1021 | put_page(hpage); | ||
1022 | get_page(p); | ||
1023 | } | ||
1024 | lock_page(p); | ||
1025 | unlock_page(hpage); | ||
1026 | *hpagep = p; | ||
1027 | } | ||
1028 | /* THP is split, so ppage should be the real poisoned page. */ | ||
1029 | ppage = p; | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | /* | ||
1034 | * First collect all the processes that have the page | 980 | * First collect all the processes that have the page |
1035 | * mapped in dirty form. This has to be done before try_to_unmap, | 981 | * mapped in dirty form. This has to be done before try_to_unmap, |
1036 | * because ttu takes the rmap data structures down. | 982 | * because ttu takes the rmap data structures down. |
@@ -1039,12 +985,12 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
1039 | * there's nothing that can be done. | 985 | * there's nothing that can be done. |
1040 | */ | 986 | */ |
1041 | if (kill) | 987 | if (kill) |
1042 | collect_procs(ppage, &tokill, flags & MF_ACTION_REQUIRED); | 988 | collect_procs(hpage, &tokill, flags & MF_ACTION_REQUIRED); |
1043 | 989 | ||
1044 | ret = try_to_unmap(ppage, ttu); | 990 | ret = try_to_unmap(hpage, ttu); |
1045 | if (ret != SWAP_SUCCESS) | 991 | if (ret != SWAP_SUCCESS) |
1046 | printk(KERN_ERR "MCE %#lx: failed to unmap page (mapcount=%d)\n", | 992 | printk(KERN_ERR "MCE %#lx: failed to unmap page (mapcount=%d)\n", |
1047 | pfn, page_mapcount(ppage)); | 993 | pfn, page_mapcount(hpage)); |
1048 | 994 | ||
1049 | /* | 995 | /* |
1050 | * Now that the dirty bit has been propagated to the | 996 | * Now that the dirty bit has been propagated to the |
@@ -1056,7 +1002,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, | |||
1056 | * use a more force-full uncatchable kill to prevent | 1002 | * use a more force-full uncatchable kill to prevent |
1057 | * any accesses to the poisoned memory. | 1003 | * any accesses to the poisoned memory. |
1058 | */ | 1004 | */ |
1059 | forcekill = PageDirty(ppage) || (flags & MF_MUST_KILL); | 1005 | forcekill = PageDirty(hpage) || (flags & MF_MUST_KILL); |
1060 | kill_procs(&tokill, forcekill, trapno, | 1006 | kill_procs(&tokill, forcekill, trapno, |
1061 | ret != SWAP_SUCCESS, p, pfn, flags); | 1007 | ret != SWAP_SUCCESS, p, pfn, flags); |
1062 | 1008 | ||
@@ -1102,6 +1048,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1102 | struct page_state *ps; | 1048 | struct page_state *ps; |
1103 | struct page *p; | 1049 | struct page *p; |
1104 | struct page *hpage; | 1050 | struct page *hpage; |
1051 | struct page *orig_head; | ||
1105 | int res; | 1052 | int res; |
1106 | unsigned int nr_pages; | 1053 | unsigned int nr_pages; |
1107 | unsigned long page_flags; | 1054 | unsigned long page_flags; |
@@ -1117,7 +1064,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1117 | } | 1064 | } |
1118 | 1065 | ||
1119 | p = pfn_to_page(pfn); | 1066 | p = pfn_to_page(pfn); |
1120 | hpage = compound_head(p); | 1067 | orig_head = hpage = compound_head(p); |
1121 | if (TestSetPageHWPoison(p)) { | 1068 | if (TestSetPageHWPoison(p)) { |
1122 | printk(KERN_ERR "MCE %#lx: already hardware poisoned\n", pfn); | 1069 | printk(KERN_ERR "MCE %#lx: already hardware poisoned\n", pfn); |
1123 | return 0; | 1070 | return 0; |
@@ -1180,6 +1127,21 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1180 | } | 1127 | } |
1181 | } | 1128 | } |
1182 | 1129 | ||
1130 | if (!PageHuge(p) && PageTransHuge(hpage)) { | ||
1131 | if (!PageAnon(hpage)) { | ||
1132 | pr_err("MCE: %#lx: non anonymous thp\n", pfn); | ||
1133 | put_page(p); | ||
1134 | return -EBUSY; | ||
1135 | } | ||
1136 | if (unlikely(split_huge_page(hpage))) { | ||
1137 | pr_err("MCE: %#lx: thp split failed\n", pfn); | ||
1138 | put_page(p); | ||
1139 | return -EBUSY; | ||
1140 | } | ||
1141 | VM_BUG_ON_PAGE(!page_count(p), p); | ||
1142 | hpage = compound_head(p); | ||
1143 | } | ||
1144 | |||
1183 | /* | 1145 | /* |
1184 | * We ignore non-LRU pages for good reasons. | 1146 | * We ignore non-LRU pages for good reasons. |
1185 | * - PG_locked is only well defined for LRU pages and a few others | 1147 | * - PG_locked is only well defined for LRU pages and a few others |
@@ -1189,9 +1151,9 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1189 | * walked by the page reclaim code, however that's not a big loss. | 1151 | * walked by the page reclaim code, however that's not a big loss. |
1190 | */ | 1152 | */ |
1191 | if (!PageHuge(p)) { | 1153 | if (!PageHuge(p)) { |
1192 | if (!PageLRU(hpage)) | 1154 | if (!PageLRU(p)) |
1193 | shake_page(hpage, 0); | 1155 | shake_page(p, 0); |
1194 | if (!PageLRU(hpage)) { | 1156 | if (!PageLRU(p)) { |
1195 | /* | 1157 | /* |
1196 | * shake_page could have turned it free. | 1158 | * shake_page could have turned it free. |
1197 | */ | 1159 | */ |
@@ -1212,7 +1174,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1212 | * The page could have changed compound pages during the locking. | 1174 | * The page could have changed compound pages during the locking. |
1213 | * If this happens just bail out. | 1175 | * If this happens just bail out. |
1214 | */ | 1176 | */ |
1215 | if (compound_head(p) != hpage) { | 1177 | if (PageCompound(p) && compound_head(p) != orig_head) { |
1216 | action_result(pfn, MSG_DIFFERENT_COMPOUND, IGNORED); | 1178 | action_result(pfn, MSG_DIFFERENT_COMPOUND, IGNORED); |
1217 | res = -EBUSY; | 1179 | res = -EBUSY; |
1218 | goto out; | 1180 | goto out; |