Skip to content

Commit

Permalink
HWPOISON: soft offlining for non-lru movable page
Browse files Browse the repository at this point in the history
Extend soft offlining framework to support non-lru page, which already
support migration after commit bda807d ("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/[email protected]
Signed-off-by: Yisheng Xie <[email protected]>
Suggested-by: Michal Hocko <[email protected]>
Suggested-by: Minchan Kim <[email protected]>
Reviewed-by: Minchan Kim <[email protected]>
Acked-by: Naoya Horiguchi <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Hanjun Guo <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Mel Gorman <[email protected]>
Cc: Reza Arbab <[email protected]>
Cc: Taku Izumi <[email protected]>
Cc: Vitaly Kuznetsov <[email protected]>
Cc: Xishi Qiu <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Yisheng Xie authored and torvalds committed Feb 25, 2017
1 parent cbae017 commit 85fbe5d
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions mm/memory-failure.c
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,8 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags)
{
int ret = __get_any_page(page, pfn, flags);

if (ret == 1 && !PageHuge(page) && !PageLRU(page)) {
if (ret == 1 && !PageHuge(page) &&
!PageLRU(page) && !__PageMovable(page)) {
/*
* Try to free it.
*/
Expand Down Expand Up @@ -1649,26 +1650,31 @@ static int __soft_offline_page(struct page *page, int flags)
* Try to migrate to a new page instead. migrate.c
* handles a large number of cases for us.
*/
ret = isolate_lru_page(page);
if (PageLRU(page))
ret = isolate_lru_page(page);
else
ret = isolate_movable_page(page, ISOLATE_UNEVICTABLE);
/*
* Drop page reference which is came from get_any_page()
* successful isolate_lru_page() already took another one.
*/
put_hwpoison_page(page);
if (!ret) {
LIST_HEAD(pagelist);
inc_node_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
/*
* After isolated lru page, the PageLRU will be cleared,
* so use !__PageMovable instead for LRU page's mapping
* cannot have PAGE_MAPPING_MOVABLE.
*/
if (!__PageMovable(page))
inc_node_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
list_add(&page->lru, &pagelist);
ret = migrate_pages(&pagelist, new_page, NULL, MPOL_MF_MOVE_ALL,
MIGRATE_SYNC, MR_MEMORY_FAILURE);
if (ret) {
if (!list_empty(&pagelist)) {
list_del(&page->lru);
dec_node_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
putback_lru_page(page);
}
if (!list_empty(&pagelist))
putback_movable_pages(&pagelist);

pr_info("soft offline: %#lx: migration failed %d, type %lx\n",
pfn, ret, page->flags);
Expand Down

0 comments on commit 85fbe5d

Please sign in to comment.