diff options
Diffstat (limited to 'mm/memory-failure.c')
-rw-r--r-- | mm/memory-failure.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index ea5a93659488..1f4446a90cef 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -1146,8 +1146,11 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | if (!PageHuge(p) && PageTransHuge(hpage)) { | 1148 | if (!PageHuge(p) && PageTransHuge(hpage)) { |
1149 | if (unlikely(split_huge_page(hpage))) { | 1149 | if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) { |
1150 | pr_err("MCE: %#lx: thp split failed\n", pfn); | 1150 | if (!PageAnon(hpage)) |
1151 | pr_err("MCE: %#lx: non anonymous thp\n", pfn); | ||
1152 | else | ||
1153 | pr_err("MCE: %#lx: thp split failed\n", pfn); | ||
1151 | if (TestClearPageHWPoison(p)) | 1154 | if (TestClearPageHWPoison(p)) |
1152 | atomic_long_sub(nr_pages, &num_poisoned_pages); | 1155 | atomic_long_sub(nr_pages, &num_poisoned_pages); |
1153 | put_page(p); | 1156 | put_page(p); |
@@ -1538,6 +1541,8 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags) | |||
1538 | */ | 1541 | */ |
1539 | ret = __get_any_page(page, pfn, 0); | 1542 | ret = __get_any_page(page, pfn, 0); |
1540 | if (!PageLRU(page)) { | 1543 | if (!PageLRU(page)) { |
1544 | /* Drop page reference which is from __get_any_page() */ | ||
1545 | put_page(page); | ||
1541 | pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", | 1546 | pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", |
1542 | pfn, page->flags); | 1547 | pfn, page->flags); |
1543 | return -EIO; | 1548 | return -EIO; |
@@ -1567,13 +1572,12 @@ static int soft_offline_huge_page(struct page *page, int flags) | |||
1567 | unlock_page(hpage); | 1572 | unlock_page(hpage); |
1568 | 1573 | ||
1569 | ret = isolate_huge_page(hpage, &pagelist); | 1574 | ret = isolate_huge_page(hpage, &pagelist); |
1570 | if (ret) { | 1575 | /* |
1571 | /* | 1576 | * get_any_page() and isolate_huge_page() takes a refcount each, |
1572 | * get_any_page() and isolate_huge_page() takes a refcount each, | 1577 | * so need to drop one here. |
1573 | * so need to drop one here. | 1578 | */ |
1574 | */ | 1579 | put_page(hpage); |
1575 | put_page(hpage); | 1580 | if (!ret) { |
1576 | } else { | ||
1577 | pr_info("soft offline: %#lx hugepage failed to isolate\n", pfn); | 1581 | pr_info("soft offline: %#lx hugepage failed to isolate\n", pfn); |
1578 | return -EBUSY; | 1582 | return -EBUSY; |
1579 | } | 1583 | } |