diff --git a/mm/memory-failure.c b/mm/memory-failure.c index a04980a8980effaf5e436747514b094a89292efc..63b26a9cca33553d2fe83e3150d85e56c8efbd16 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1892,6 +1892,7 @@ int soft_offline_page(struct page *page, int flags) { int ret; unsigned long pfn = page_to_pfn(page); + bool try_again = true; if (is_zone_device_page(page)) { pr_debug_ratelimited("soft_offline: %#lx page is device page\n", @@ -1908,6 +1909,7 @@ int soft_offline_page(struct page *page, int flags) return 0; } +retry: get_online_mems(); ret = get_any_page(page, pfn, flags); put_online_mems(); @@ -1915,7 +1917,10 @@ int soft_offline_page(struct page *page, int flags) if (ret > 0) ret = soft_offline_in_use_page(page); else if (ret == 0) - ret = soft_offline_free_page(page); + if (soft_offline_free_page(page) && try_again) { + try_again = false; + goto retry; + } return ret; }