Skip to content

Commit fcc0062

Browse files
nhoriguchitorvalds
authored andcommitted
mm/hwpoison: retry with shake_page() for unhandlable pages
HWPoisonHandlable() sometimes returns false for typical user pages due to races with average memory events like transfers over LRU lists. This causes failures in hwpoison handling. There's retry code for such a case but does not work because the retry loop reaches the retry limit too quickly before the page settles down to handlable state. Let get_any_page() call shake_page() to fix it. [[email protected]: get_any_page(): return -EIO when retry limit reached] Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Fixes: 25182f0 ("mm,hwpoison: fix race with hugetlb page allocation") Signed-off-by: Naoya Horiguchi <[email protected]> Reported-by: Tony Luck <[email protected]> Reviewed-by: Yang Shi <[email protected]> Cc: Oscar Salvador <[email protected]> Cc: Muchun Song <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Michal Hocko <[email protected]> Cc: <[email protected]> [5.13+] Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent f56ce41 commit fcc0062

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

mm/memory-failure.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ static int __get_hwpoison_page(struct page *page)
11461146
* unexpected races caused by taking a page refcount.
11471147
*/
11481148
if (!HWPoisonHandlable(head))
1149-
return 0;
1149+
return -EBUSY;
11501150

11511151
if (PageTransHuge(head)) {
11521152
/*
@@ -1199,9 +1199,15 @@ static int get_any_page(struct page *p, unsigned long flags)
11991199
}
12001200
goto out;
12011201
} else if (ret == -EBUSY) {
1202-
/* We raced with freeing huge page to buddy, retry. */
1203-
if (pass++ < 3)
1202+
/*
1203+
* We raced with (possibly temporary) unhandlable
1204+
* page, retry.
1205+
*/
1206+
if (pass++ < 3) {
1207+
shake_page(p, 1);
12041208
goto try_again;
1209+
}
1210+
ret = -EIO;
12051211
goto out;
12061212
}
12071213
}

0 commit comments

Comments
 (0)