aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/memory-failure.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index fee648b9d393..473f15a3356d 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -942,6 +942,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
942 struct page *p; 942 struct page *p;
943 struct page *hpage; 943 struct page *hpage;
944 int res; 944 int res;
945 unsigned int nr_pages;
945 946
946 if (!sysctl_memory_failure_recovery) 947 if (!sysctl_memory_failure_recovery)
947 panic("Memory failure from trap %d on page %lx", trapno, pfn); 948 panic("Memory failure from trap %d on page %lx", trapno, pfn);
@@ -960,7 +961,8 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
960 return 0; 961 return 0;
961 } 962 }
962 963
963 atomic_long_add(1, &mce_bad_pages); 964 nr_pages = 1 << compound_order(hpage);
965 atomic_long_add(nr_pages, &mce_bad_pages);
964 966
965 /* 967 /*
966 * We need/can do nothing about count=0 pages. 968 * We need/can do nothing about count=0 pages.
@@ -1024,7 +1026,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
1024 } 1026 }
1025 if (hwpoison_filter(p)) { 1027 if (hwpoison_filter(p)) {
1026 if (TestClearPageHWPoison(p)) 1028 if (TestClearPageHWPoison(p))
1027 atomic_long_dec(&mce_bad_pages); 1029 atomic_long_sub(nr_pages, &mce_bad_pages);
1028 unlock_page(hpage); 1030 unlock_page(hpage);
1029 put_page(hpage); 1031 put_page(hpage);
1030 return 0; 1032 return 0;
@@ -1123,6 +1125,7 @@ int unpoison_memory(unsigned long pfn)
1123 struct page *page; 1125 struct page *page;
1124 struct page *p; 1126 struct page *p;
1125 int freeit = 0; 1127 int freeit = 0;
1128 unsigned int nr_pages;
1126 1129
1127 if (!pfn_valid(pfn)) 1130 if (!pfn_valid(pfn))
1128 return -ENXIO; 1131 return -ENXIO;
@@ -1135,9 +1138,11 @@ int unpoison_memory(unsigned long pfn)
1135 return 0; 1138 return 0;
1136 } 1139 }
1137 1140
1141 nr_pages = 1 << compound_order(page);
1142
1138 if (!get_page_unless_zero(page)) { 1143 if (!get_page_unless_zero(page)) {
1139 if (TestClearPageHWPoison(p)) 1144 if (TestClearPageHWPoison(p))
1140 atomic_long_dec(&mce_bad_pages); 1145 atomic_long_sub(nr_pages, &mce_bad_pages);
1141 pr_debug("MCE: Software-unpoisoned free page %#lx\n", pfn); 1146 pr_debug("MCE: Software-unpoisoned free page %#lx\n", pfn);
1142 return 0; 1147 return 0;
1143 } 1148 }
@@ -1149,9 +1154,9 @@ int unpoison_memory(unsigned long pfn)
1149 * the PG_hwpoison page will be caught and isolated on the entrance to 1154 * the PG_hwpoison page will be caught and isolated on the entrance to
1150 * the free buddy page pool. 1155 * the free buddy page pool.
1151 */ 1156 */
1152 if (TestClearPageHWPoison(p)) { 1157 if (TestClearPageHWPoison(page)) {
1153 pr_debug("MCE: Software-unpoisoned page %#lx\n", pfn); 1158 pr_debug("MCE: Software-unpoisoned page %#lx\n", pfn);
1154 atomic_long_dec(&mce_bad_pages); 1159 atomic_long_sub(nr_pages, &mce_bad_pages);
1155 freeit = 1; 1160 freeit = 1;
1156 } 1161 }
1157 if (PageHuge(p)) 1162 if (PageHuge(p))