diff options
author | Yisheng Xie <xieyisheng1@huawei.com> | 2017-02-24 17:57:35 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-02-24 20:46:55 -0500 |
commit | 85fbe5d1b50cf6f83b4123ca28d6fab84275824c (patch) | |
tree | 9a119801eab302aebee188d6666b189d2fb0a200 /mm | |
parent | cbae0170e5329c79c0a36a81fedd2800146aca12 (diff) |
HWPOISON: soft offlining for non-lru movable page
Extend soft offlining framework to support non-lru page, which already
support migration after commit bda807d44454 ("mm: migrate: support
non-lru movable page migration")
When memory corrected errors occur on a non-lru movable page, we can
choose to stop using it by migrating data onto another page and disable
the original (maybe half-broken) one.
Link: http://lkml.kernel.org/r/1485867981-16037-4-git-send-email-ysxie@foxmail.com
Signed-off-by: Yisheng Xie <xieyisheng1@huawei.com>
Suggested-by: Michal Hocko <mhocko@kernel.org>
Suggested-by: Minchan Kim <minchan@kernel.org>
Reviewed-by: Minchan Kim <minchan@kernel.org>
Acked-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Hanjun Guo <guohanjun@huawei.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Reza Arbab <arbab@linux.vnet.ibm.com>
Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: Xishi Qiu <qiuxishi@huawei.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.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index f283c7e0a2a3..3d0f2fd4bf73 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c | |||
@@ -1527,7 +1527,8 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags) | |||
1527 | { | 1527 | { |
1528 | int ret = __get_any_page(page, pfn, flags); | 1528 | int ret = __get_any_page(page, pfn, flags); |
1529 | 1529 | ||
1530 | if (ret == 1 && !PageHuge(page) && !PageLRU(page)) { | 1530 | if (ret == 1 && !PageHuge(page) && |
1531 | !PageLRU(page) && !__PageMovable(page)) { | ||
1531 | /* | 1532 | /* |
1532 | * Try to free it. | 1533 | * Try to free it. |
1533 | */ | 1534 | */ |
@@ -1649,7 +1650,10 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1649 | * Try to migrate to a new page instead. migrate.c | 1650 | * Try to migrate to a new page instead. migrate.c |
1650 | * handles a large number of cases for us. | 1651 | * handles a large number of cases for us. |
1651 | */ | 1652 | */ |
1652 | ret = isolate_lru_page(page); | 1653 | if (PageLRU(page)) |
1654 | ret = isolate_lru_page(page); | ||
1655 | else | ||
1656 | ret = isolate_movable_page(page, ISOLATE_UNEVICTABLE); | ||
1653 | /* | 1657 | /* |
1654 | * Drop page reference which is came from get_any_page() | 1658 | * Drop page reference which is came from get_any_page() |
1655 | * successful isolate_lru_page() already took another one. | 1659 | * successful isolate_lru_page() already took another one. |
@@ -1657,18 +1661,20 @@ static int __soft_offline_page(struct page *page, int flags) | |||
1657 | put_hwpoison_page(page); | 1661 | put_hwpoison_page(page); |
1658 | if (!ret) { | 1662 | if (!ret) { |
1659 | LIST_HEAD(pagelist); | 1663 | LIST_HEAD(pagelist); |
1660 | inc_node_page_state(page, NR_ISOLATED_ANON + | 1664 | /* |
1661 | page_is_file_cache(page)); | 1665 | * After isolated lru page, the PageLRU will be cleared, |
1666 | * so use !__PageMovable instead for LRU page's mapping | ||
1667 | * cannot have PAGE_MAPPING_MOVABLE. | ||
1668 | */ | ||
1669 | if (!__PageMovable(page)) | ||
1670 | inc_node_page_state(page, NR_ISOLATED_ANON + | ||
1671 | page_is_file_cache(page)); | ||
1662 | list_add(&page->lru, &pagelist); | 1672 | list_add(&page->lru, &pagelist); |
1663 | ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, | 1673 | ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL, |
1664 | MIGRATE_SYNC, MR_MEMORY_FAILURE); | 1674 | MIGRATE_SYNC, MR_MEMORY_FAILURE); |
1665 | if (ret) { | 1675 | if (ret) { |
1666 | if (!list_empty(&pagelist)) { | 1676 | if (!list_empty(&pagelist)) |
1667 | list_del(&page->lru); | 1677 | putback_movable_pages(&pagelist); |
1668 | dec_node_page_state(page, NR_ISOLATED_ANON + | ||
1669 | page_is_file_cache(page)); | ||
1670 | putback_lru_page(page); | ||
1671 | } | ||
1672 | 1678 | ||
1673 | pr_info("soft offline: %#lx: migration failed %d, type %lx\n", | 1679 | pr_info("soft offline: %#lx: migration failed %d, type %lx\n", |
1674 | pfn, ret, page->flags); | 1680 | pfn, ret, page->flags); |