Skip to content

Commit bf6445b

Browse files
MiaoheLintorvalds
authored andcommitted
mm/memory-failure.c: make non-LRU movable pages unhandlable
We can not really handle non-LRU movable pages in memory failure. Typically they are balloon, zsmalloc, etc. Assuming we run into a base (4K) non-LRU movable page, we could reach as far as identify_page_state(), it should not fall into any category except me_unknown. For the non-LRU compound movable pages, they could be taken for transhuge pages but it's unexpected to split non-LRU movable pages using split_huge_page_to_list in memory_failure. So we could just simply make non-LRU movable pages unhandlable to avoid these possible nasty cases. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Miaohe Lin <[email protected]> Suggested-by: Yang Shi <[email protected]> Reviewed-by: Yang Shi <[email protected]> Acked-by: Naoya Horiguchi <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Mike Kravetz <[email protected]> Cc: Tony Luck <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 593396b commit bf6445b

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

mm/memory-failure.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,12 +1176,18 @@ void ClearPageHWPoisonTakenOff(struct page *page)
11761176
* does not return true for hugetlb or device memory pages, so it's assumed
11771177
* to be called only in the context where we never have such pages.
11781178
*/
1179-
static inline bool HWPoisonHandlable(struct page *page)
1179+
static inline bool HWPoisonHandlable(struct page *page, unsigned long flags)
11801180
{
1181-
return PageLRU(page) || __PageMovable(page) || is_free_buddy_page(page);
1181+
bool movable = false;
1182+
1183+
/* Soft offline could mirgate non-LRU movable pages */
1184+
if ((flags & MF_SOFT_OFFLINE) && __PageMovable(page))
1185+
movable = true;
1186+
1187+
return movable || PageLRU(page) || is_free_buddy_page(page);
11821188
}
11831189

1184-
static int __get_hwpoison_page(struct page *page)
1190+
static int __get_hwpoison_page(struct page *page, unsigned long flags)
11851191
{
11861192
struct page *head = compound_head(page);
11871193
int ret = 0;
@@ -1196,7 +1202,7 @@ static int __get_hwpoison_page(struct page *page)
11961202
* for any unsupported type of page in order to reduce the risk of
11971203
* unexpected races caused by taking a page refcount.
11981204
*/
1199-
if (!HWPoisonHandlable(head))
1205+
if (!HWPoisonHandlable(head, flags))
12001206
return -EBUSY;
12011207

12021208
if (get_page_unless_zero(head)) {
@@ -1221,7 +1227,7 @@ static int get_any_page(struct page *p, unsigned long flags)
12211227

12221228
try_again:
12231229
if (!count_increased) {
1224-
ret = __get_hwpoison_page(p);
1230+
ret = __get_hwpoison_page(p, flags);
12251231
if (!ret) {
12261232
if (page_count(p)) {
12271233
/* We raced with an allocation, retry. */
@@ -1249,7 +1255,7 @@ static int get_any_page(struct page *p, unsigned long flags)
12491255
}
12501256
}
12511257

1252-
if (PageHuge(p) || HWPoisonHandlable(p)) {
1258+
if (PageHuge(p) || HWPoisonHandlable(p, flags)) {
12531259
ret = 1;
12541260
} else {
12551261
/*
@@ -2302,7 +2308,7 @@ int soft_offline_page(unsigned long pfn, int flags)
23022308

23032309
retry:
23042310
get_online_mems();
2305-
ret = get_hwpoison_page(page, flags);
2311+
ret = get_hwpoison_page(page, flags | MF_SOFT_OFFLINE);
23062312
put_online_mems();
23072313

23082314
if (ret > 0) {

0 commit comments

Comments
 (0)