aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorNaoya Horiguchi <n-horiguchi@ah.jp.nec.com>2016-01-15 19:57:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-15 20:56:32 -0500
commitacc14dc4bd484f1fc8c227dd9fc2a1e592312d2b (patch)
treec7c15039ad08887ad1d17f0783e9e27442a1aa04 /mm
parent4aae8d1c051ea00b456da6811bc36d1f69de5445 (diff)
mm: soft-offline: clean up soft_offline_page()
soft_offline_page() has some deeply indented code, that's the sign of demand for cleanup. So let's do this. No functionality change. Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: "Kirill A. Shutemov" <kirill@shutemov.name> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/memory-failure.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 1b99403d76f2..2015c9a06cae 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1684,6 +1684,49 @@ static int __soft_offline_page(struct page *page, int flags)
1684 return ret; 1684 return ret;
1685} 1685}
1686 1686
1687static int soft_offline_in_use_page(struct page *page, int flags)
1688{
1689 int ret;
1690 struct page *hpage = compound_head(page);
1691
1692 if (!PageHuge(page) && PageTransHuge(hpage)) {
1693 lock_page(hpage);
1694 ret = split_huge_page(hpage);
1695 unlock_page(hpage);
1696 if (unlikely(ret || PageTransCompound(page) ||
1697 !PageAnon(page))) {
1698 pr_info("soft offline: %#lx: failed to split THP\n",
1699 page_to_pfn(page));
1700 if (flags & MF_COUNT_INCREASED)
1701 put_hwpoison_page(hpage);
1702 return -EBUSY;
1703 }
1704 get_hwpoison_page(page);
1705 put_hwpoison_page(hpage);
1706 }
1707
1708 if (PageHuge(page))
1709 ret = soft_offline_huge_page(page, flags);
1710 else
1711 ret = __soft_offline_page(page, flags);
1712
1713 return ret;
1714}
1715
1716static void soft_offline_free_page(struct page *page)
1717{
1718 if (PageHuge(page)) {
1719 struct page *hpage = compound_head(page);
1720
1721 set_page_hwpoison_huge_page(hpage);
1722 if (!dequeue_hwpoisoned_huge_page(hpage))
1723 num_poisoned_pages_add(1 << compound_order(hpage));
1724 } else {
1725 if (!TestSetPageHWPoison(page))
1726 num_poisoned_pages_inc();
1727 }
1728}
1729
1687/** 1730/**
1688 * soft_offline_page - Soft offline a page. 1731 * soft_offline_page - Soft offline a page.
1689 * @page: page to offline 1732 * @page: page to offline
@@ -1710,7 +1753,6 @@ int soft_offline_page(struct page *page, int flags)
1710{ 1753{
1711 int ret; 1754 int ret;
1712 unsigned long pfn = page_to_pfn(page); 1755 unsigned long pfn = page_to_pfn(page);
1713 struct page *hpage = compound_head(page);
1714 1756
1715 if (PageHWPoison(page)) { 1757 if (PageHWPoison(page)) {
1716 pr_info("soft offline: %#lx page already poisoned\n", pfn); 1758 pr_info("soft offline: %#lx page already poisoned\n", pfn);
@@ -1723,36 +1765,10 @@ int soft_offline_page(struct page *page, int flags)
1723 ret = get_any_page(page, pfn, flags); 1765 ret = get_any_page(page, pfn, flags);
1724 put_online_mems(); 1766 put_online_mems();
1725 1767
1726 if (ret > 0) { /* for in-use pages */ 1768 if (ret > 0)
1727 if (!PageHuge(page) && PageTransHuge(hpage)) { 1769 ret = soft_offline_in_use_page(page, flags);
1728 lock_page(hpage); 1770 else if (ret == 0)
1729 ret = split_huge_page(hpage); 1771 soft_offline_free_page(page);
1730 unlock_page(hpage);
1731 if (unlikely(ret || PageTransCompound(page) ||
1732 !PageAnon(page))) {
1733 pr_info("soft offline: %#lx: failed to split THP\n",
1734 pfn);
1735 if (flags & MF_COUNT_INCREASED)
1736 put_hwpoison_page(hpage);
1737 return -EBUSY;
1738 }
1739 get_hwpoison_page(page);
1740 put_hwpoison_page(hpage);
1741 }
1742 1772
1743 if (PageHuge(page))
1744 ret = soft_offline_huge_page(page, flags);
1745 else
1746 ret = __soft_offline_page(page, flags);
1747 } else if (ret == 0) { /* for free pages */
1748 if (PageHuge(page)) {
1749 set_page_hwpoison_huge_page(hpage);
1750 if (!dequeue_hwpoisoned_huge_page(hpage))
1751 num_poisoned_pages_add(1 << compound_order(hpage));
1752 } else {
1753 if (!TestSetPageHWPoison(page))
1754 num_poisoned_pages_inc();
1755 }
1756 }
1757 return ret; 1773 return ret;
1758} 1774}