diff options
Diffstat (limited to 'mm/memory-failure.c')
-rw-r--r-- | mm/memory-failure.c | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 5ceb8253e33b..5420d3819adf 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -1174,9 +1174,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1174 | pr_err("MCE: %#lx: thp split failed\n", pfn); | 1174 | pr_err("MCE: %#lx: thp split failed\n", pfn); |
1175 | if (TestClearPageHWPoison(p)) | 1175 | if (TestClearPageHWPoison(p)) |
1176 | atomic_long_sub(nr_pages, &num_poisoned_pages); | 1176 | atomic_long_sub(nr_pages, &num_poisoned_pages); |
1177 | put_page(p); | 1177 | put_hwpoison_page(p); |
1178 | if (p != hpage) | ||
1179 | put_page(hpage); | ||
1180 | return -EBUSY; | 1178 | return -EBUSY; |
1181 | } | 1179 | } |
1182 | VM_BUG_ON_PAGE(!page_count(p), p); | 1180 | VM_BUG_ON_PAGE(!page_count(p), p); |
@@ -1237,14 +1235,14 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1237 | printk(KERN_ERR "MCE %#lx: just unpoisoned\n", pfn); | 1235 | printk(KERN_ERR "MCE %#lx: just unpoisoned\n", pfn); |
1238 | atomic_long_sub(nr_pages, &num_poisoned_pages); | 1236 | atomic_long_sub(nr_pages, &num_poisoned_pages); |
1239 | unlock_page(hpage); | 1237 | unlock_page(hpage); |
1240 | put_page(hpage); | 1238 | put_hwpoison_page(hpage); |
1241 | return 0; | 1239 | return 0; |
1242 | } | 1240 | } |
1243 | if (hwpoison_filter(p)) { | 1241 | if (hwpoison_filter(p)) { |
1244 | if (TestClearPageHWPoison(p)) | 1242 | if (TestClearPageHWPoison(p)) |
1245 | atomic_long_sub(nr_pages, &num_poisoned_pages); | 1243 | atomic_long_sub(nr_pages, &num_poisoned_pages); |
1246 | unlock_page(hpage); | 1244 | unlock_page(hpage); |
1247 | put_page(hpage); | 1245 | put_hwpoison_page(hpage); |
1248 | return 0; | 1246 | return 0; |
1249 | } | 1247 | } |
1250 | 1248 | ||
@@ -1258,7 +1256,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) | |||
1258 | if (PageHuge(p) && PageTail(p) && TestSetPageHWPoison(hpage)) { | 1256 | if (PageHuge(p) && PageTail(p) && TestSetPageHWPoison(hpage)) { |
1259 | action_result(pfn, MF_MSG_POISONED_HUGE, MF_IGNORED); | 1257 | action_result(pfn, MF_MSG_POISONED_HUGE, MF_IGNORED); |
1260 | unlock_page(hpage); | 1258 | unlock_page(hpage); |
1261 | put_page(hpage); | 1259 | put_hwpoison_page(hpage); |
1262 | return 0; | 1260 | return 0; |
1263 | } | 1261 | } |
1264 | /* | 1262 | /* |
@@ -1492,9 +1490,9 @@ int unpoison_memory(unsigned long pfn) | |||
1492 | } | 1490 | } |
1493 | unlock_page(page); | 1491 | unlock_page(page); |
1494 | 1492 | ||
1495 | put_page(page); | 1493 | put_hwpoison_page(page); |
1496 | if (freeit && !(pfn == my_zero_pfn(0) && page_count(p) == 1)) | 1494 | if (freeit && !(pfn == my_zero_pfn(0) && page_count(p) == 1)) |
1497 | put_page(page); | 1495 | put_hwpoison_page(page); |
1498 | 1496 | ||
1499 | return 0; | 1497 | return 0; |
1500 | } | 1498 | } |
@@ -1554,7 +1552,7 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags) | |||
1554 | /* | 1552 | /* |
1555 | * Try to free it. | 1553 | * Try to free it. |
1556 | */ | 1554 | */ |
1557 | put_page(page); | 1555 | put_hwpoison_page(page); |
1558 | shake_page(page, 1); | 1556 | shake_page(page, 1); |
1559 | 1557 | ||
1560 | /* | 1558 | /* |
@@ -1563,7 +1561,7 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags) | |||
1563 | ret = __get_any_page(page, pfn, 0); | 1561 | ret = __get_any_page(page, pfn, 0); |
1564 | if (!PageLRU(page)) { | 1562 | if (!PageLRU(page)) { |
1565 | /* Drop page reference which is from __get_any_page() */ | 1563 | /* Drop page reference which is from __get_any_page() */ |
1566 | put_page(page); | 1564 | put_hwpoison_page(page); |
1567 | pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", | 1565 | pr_info("soft_offline: %#lx: unknown non LRU page type %lx\n", |
1568 | pfn, page->flags); | 1566 | pfn, page->flags); |
1569 | return -EIO; | 1567 | return -EIO; |
@@ -1586,7 +1584,7 @@ static int soft_offline_huge_page(struct page *page, int flags) | |||
1586 | lock_page(hpage); | 1584 | lock_page(hpage); |
1587 | if (PageHWPoison(hpage)) { | 1585 | if (PageHWPoison(hpage)) { |
1588 | unlock_page(hpage); | 1586 | unlock_page(hpage); |
1589 | put_page(hpage); | 1587 | put_hwpoison_page(hpage); |
1590 | pr_info("soft offline: %#lx hugepage already poisoned\n", pfn); | 1588 | pr_info("soft offline: %#lx hugepage already poisoned\n", pfn); |
1591 | return -EBUSY; | 1589 | return -EBUSY; |
1592 | } | 1590 | } |
@@ -1597,7 +1595,7 @@ static int soft_offline_huge_page(struct page *page, int flags) | |||
1597 | * get_any_page() and isolate_huge_page() takes a refcount each, | 1595 | * get_any_page() and isolate_huge_page() takes a refcount each, |
1598 | * so need to drop one here. | 1596 | * so need to drop one here. |
1599 | */ | 1597 | */ |
1600 | put_page(hpage); | 1598 | put_hwpoison_page(hpage); |
1601 | if (!ret) { | 1599 | if (!ret) { |
1602 | pr_info("soft offline: %#lx hugepage failed to isolate\n", pfn); | 1600 | pr_info("soft offline: %#lx hugepage failed to isolate\n", pfn); |
1603 | return -EBUSY; | 1601 | return -EBUSY; |
@@ -1646,7 +1644,7 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1646 | wait_on_page_writeback(page); | 1644 | wait_on_page_writeback(page); |
1647 | if (PageHWPoison(page)) { | 1645 | if (PageHWPoison(page)) { |
1648 | unlock_page(page); | 1646 | unlock_page(page); |
1649 | put_page(page); | 1647 | put_hwpoison_page(page); |
1650 | pr_info("soft offline: %#lx page already poisoned\n", pfn); | 1648 | pr_info("soft offline: %#lx page already poisoned\n", pfn); |
1651 | return -EBUSY; | 1649 | return -EBUSY; |
1652 | } | 1650 | } |
@@ -1661,7 +1659,7 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1661 | * would need to fix isolation locking first. | 1659 | * would need to fix isolation locking first. |
1662 | */ | 1660 | */ |
1663 | if (ret == 1) { | 1661 | if (ret == 1) { |
1664 | put_page(page); | 1662 | put_hwpoison_page(page); |
1665 | pr_info("soft_offline: %#lx: invalidated\n", pfn); | 1663 | pr_info("soft_offline: %#lx: invalidated\n", pfn); |
1666 | SetPageHWPoison(page); | 1664 | SetPageHWPoison(page); |
1667 | atomic_long_inc(&num_poisoned_pages); | 1665 | atomic_long_inc(&num_poisoned_pages); |
@@ -1678,7 +1676,7 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1678 | * Drop page reference which is came from get_any_page() | 1676 | * Drop page reference which is came from get_any_page() |
1679 | * successful isolate_lru_page() already took another one. | 1677 | * successful isolate_lru_page() already took another one. |
1680 | */ | 1678 | */ |
1681 | put_page(page); | 1679 | put_hwpoison_page(page); |
1682 | if (!ret) { | 1680 | if (!ret) { |
1683 | LIST_HEAD(pagelist); | 1681 | LIST_HEAD(pagelist); |
1684 | inc_zone_page_state(page, NR_ISOLATED_ANON + | 1682 | inc_zone_page_state(page, NR_ISOLATED_ANON + |
@@ -1741,7 +1739,7 @@ int soft_offline_page(struct page *page, int flags) | |||
1741 | if (PageHWPoison(page)) { | 1739 | if (PageHWPoison(page)) { |
1742 | pr_info("soft offline: %#lx page already poisoned\n", pfn); | 1740 | pr_info("soft offline: %#lx page already poisoned\n", pfn); |
1743 | if (flags & MF_COUNT_INCREASED) | 1741 | if (flags & MF_COUNT_INCREASED) |
1744 | put_page(page); | 1742 | put_hwpoison_page(page); |
1745 | return -EBUSY; | 1743 | return -EBUSY; |
1746 | } | 1744 | } |
1747 | if (!PageHuge(page) && PageTransHuge(hpage)) { | 1745 | if (!PageHuge(page) && PageTransHuge(hpage)) { |
@@ -1749,7 +1747,7 @@ int soft_offline_page(struct page *page, int flags) | |||
1749 | pr_info("soft offline: %#lx: failed to split THP\n", | 1747 | pr_info("soft offline: %#lx: failed to split THP\n", |
1750 | pfn); | 1748 | pfn); |
1751 | if (flags & MF_COUNT_INCREASED) | 1749 | if (flags & MF_COUNT_INCREASED) |
1752 | put_page(page); | 1750 | put_hwpoison_page(page); |
1753 | return -EBUSY; | 1751 | return -EBUSY; |
1754 | } | 1752 | } |
1755 | } | 1753 | } |