Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85fbe5d1 authored by Yisheng Xie's avatar Yisheng Xie Committed by Linus Torvalds
Browse files

HWPOISON: soft offlining for non-lru movable page

Extend soft offlining framework to support non-lru page, which already
support migration after commit bda807d4 ("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: default avatarYisheng Xie <xieyisheng1@huawei.com>
Suggested-by: default avatarMichal Hocko <mhocko@kernel.org>
Suggested-by: default avatarMinchan Kim <minchan@kernel.org>
Reviewed-by: default avatarMinchan Kim <minchan@kernel.org>
Acked-by: default avatarNaoya 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent cbae0170
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -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.
		 */
@@ -1649,7 +1650,10 @@ 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.
	 */
	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.
@@ -1657,18 +1661,20 @@ static int __soft_offline_page(struct page *page, int flags)
	put_hwpoison_page(page);
	if (!ret) {
		LIST_HEAD(pagelist);
		/*
		 * 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);