From: Oscar Salvador osalvador@suse.de
mainline inclusion from linux-v5.10-rc1 commit b94e02822debdf0cc473556aad7dcc859f216653 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4LE22 CVE: NA
--------------------------------
Aristeu Rozanski reported that a customer test case started to report -EBUSY after the hwpoison rework patchset.
There is a race window between spotting a free page and taking it off its buddy freelist, so it might be that by the time we try to take it off, the page has been already allocated.
This patch tries to handle such race window by trying to handle the new type of page again if the page was allocated under us.
Signed-off-by: Oscar Salvador osalvador@suse.de Reported-by: Aristeu Rozanski aris@ruivo.org Tested-by: Aristeu Rozanski aris@ruivo.org Acked-by: Naoya Horiguchi naoya.horiguchi@nec.com Signed-off-by: Ma Wupeng mawupeng1@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- mm/memory-failure.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index a04980a8980ef..63b26a9cca335 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; }