aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorWanpeng Li <liwanp@linux.vnet.ibm.com>2013-09-11 17:22:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-11 18:58:11 -0400
commit86e057734bd1c460c48ae69f8fcc3ed90eb40d59 (patch)
treee15cdc5e2766676bc04aec80d5186713428004b2 /mm
parent0be35096a145290cc0771d52adb3b241dca22604 (diff)
mm/hwpoison: drop forward reference declarations __soft_offline_page()
Drop forward reference declarations __soft_offline_page. Signed-off-by: Wanpeng Li <liwanp@linux.vnet.ibm.com> Reviewed-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Tony Luck <tony.luck@intel.com> 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.c130
1 files changed, 64 insertions, 66 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index 784a1e17c905..d04f99004c9f 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1523,72 +1523,6 @@ static int soft_offline_huge_page(struct page *page, int flags)
1523 return ret; 1523 return ret;
1524} 1524}
1525 1525
1526static int __soft_offline_page(struct page *page, int flags);
1527
1528/**
1529 * soft_offline_page - Soft offline a page.
1530 * @page: page to offline
1531 * @flags: flags. Same as memory_failure().
1532 *
1533 * Returns 0 on success, otherwise negated errno.
1534 *
1535 * Soft offline a page, by migration or invalidation,
1536 * without killing anything. This is for the case when
1537 * a page is not corrupted yet (so it's still valid to access),
1538 * but has had a number of corrected errors and is better taken
1539 * out.
1540 *
1541 * The actual policy on when to do that is maintained by
1542 * user space.
1543 *
1544 * This should never impact any application or cause data loss,
1545 * however it might take some time.
1546 *
1547 * This is not a 100% solution for all memory, but tries to be
1548 * ``good enough'' for the majority of memory.
1549 */
1550int soft_offline_page(struct page *page, int flags)
1551{
1552 int ret;
1553 unsigned long pfn = page_to_pfn(page);
1554 struct page *hpage = compound_trans_head(page);
1555
1556 if (PageHWPoison(page)) {
1557 pr_info("soft offline: %#lx page already poisoned\n", pfn);
1558 return -EBUSY;
1559 }
1560 if (!PageHuge(page) && PageTransHuge(hpage)) {
1561 if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) {
1562 pr_info("soft offline: %#lx: failed to split THP\n",
1563 pfn);
1564 return -EBUSY;
1565 }
1566 }
1567
1568 ret = get_any_page(page, pfn, flags);
1569 if (ret < 0)
1570 goto unset;
1571 if (ret) { /* for in-use pages */
1572 if (PageHuge(page))
1573 ret = soft_offline_huge_page(page, flags);
1574 else
1575 ret = __soft_offline_page(page, flags);
1576 } else { /* for free pages */
1577 if (PageHuge(page)) {
1578 set_page_hwpoison_huge_page(hpage);
1579 dequeue_hwpoisoned_huge_page(hpage);
1580 atomic_long_add(1 << compound_order(hpage),
1581 &num_poisoned_pages);
1582 } else {
1583 SetPageHWPoison(page);
1584 atomic_long_inc(&num_poisoned_pages);
1585 }
1586 }
1587unset:
1588 unset_migratetype_isolate(page, MIGRATE_MOVABLE);
1589 return ret;
1590}
1591
1592static int __soft_offline_page(struct page *page, int flags) 1526static int __soft_offline_page(struct page *page, int flags)
1593{ 1527{
1594 int ret; 1528 int ret;
@@ -1675,3 +1609,67 @@ static int __soft_offline_page(struct page *page, int flags)
1675 } 1609 }
1676 return ret; 1610 return ret;
1677} 1611}
1612
1613/**
1614 * soft_offline_page - Soft offline a page.
1615 * @page: page to offline
1616 * @flags: flags. Same as memory_failure().
1617 *
1618 * Returns 0 on success, otherwise negated errno.
1619 *
1620 * Soft offline a page, by migration or invalidation,
1621 * without killing anything. This is for the case when
1622 * a page is not corrupted yet (so it's still valid to access),
1623 * but has had a number of corrected errors and is better taken
1624 * out.
1625 *
1626 * The actual policy on when to do that is maintained by
1627 * user space.
1628 *
1629 * This should never impact any application or cause data loss,
1630 * however it might take some time.
1631 *
1632 * This is not a 100% solution for all memory, but tries to be
1633 * ``good enough'' for the majority of memory.
1634 */
1635int soft_offline_page(struct page *page, int flags)
1636{
1637 int ret;
1638 unsigned long pfn = page_to_pfn(page);
1639 struct page *hpage = compound_trans_head(page);
1640
1641 if (PageHWPoison(page)) {
1642 pr_info("soft offline: %#lx page already poisoned\n", pfn);
1643 return -EBUSY;
1644 }
1645 if (!PageHuge(page) && PageTransHuge(hpage)) {
1646 if (PageAnon(hpage) && unlikely(split_huge_page(hpage))) {
1647 pr_info("soft offline: %#lx: failed to split THP\n",
1648 pfn);
1649 return -EBUSY;
1650 }
1651 }
1652
1653 ret = get_any_page(page, pfn, flags);
1654 if (ret < 0)
1655 goto unset;
1656 if (ret) { /* for in-use pages */
1657 if (PageHuge(page))
1658 ret = soft_offline_huge_page(page, flags);
1659 else
1660 ret = __soft_offline_page(page, flags);
1661 } else { /* for free pages */
1662 if (PageHuge(page)) {
1663 set_page_hwpoison_huge_page(hpage);
1664 dequeue_hwpoisoned_huge_page(hpage);
1665 atomic_long_add(1 << compound_order(hpage),
1666 &num_poisoned_pages);
1667 } else {
1668 SetPageHWPoison(page);
1669 atomic_long_inc(&num_poisoned_pages);
1670 }
1671 }
1672unset:
1673 unset_migratetype_isolate(page, MIGRATE_MOVABLE);
1674 return ret;
1675}