forked from Minki/linux
mm,hwpoison: double-check page count in __get_any_page()
Soft offlining could fail with EIO due to the race condition with hugepage migration. This issuse became visible due to the change by previous patch that makes soft offline handler take page refcount by its own. We have no way to directly pin zero refcount page, and the page considered as a zero refcount page could be allocated just after the first check. This patch adds the second check to find the race and gives us chance to handle it more reliably. Reported-by: Qian Cai <cai@lca.pw> Signed-off-by: Naoya Horiguchi <naoya.horiguchi@nec.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com> Cc: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Cc: Aristeu Rozanski <aris@ruivo.org> Cc: Dave Hansen <dave.hansen@intel.com> Cc: David Hildenbrand <david@redhat.com> Cc: Dmitry Yakunin <zeil@yandex-team.ru> Cc: Michal Hocko <mhocko@kernel.org> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Oscar Salvador <osalvador@suse.com> Cc: Tony Luck <tony.luck@intel.com> Link: https://lkml.kernel.org/r/20200922135650.1634-14-osalvador@suse.de Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
5d1fd5dc87
commit
1f2481ddbe
@ -1707,6 +1707,9 @@ static int __get_any_page(struct page *p, unsigned long pfn, int flags)
|
||||
} else if (is_free_buddy_page(p)) {
|
||||
pr_info("%s: %#lx free buddy page\n", __func__, pfn);
|
||||
ret = 0;
|
||||
} else if (page_count(p)) {
|
||||
/* raced with allocation */
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
pr_info("%s: %#lx: unknown zero refcount page type %lx\n",
|
||||
__func__, pfn, p->flags);
|
||||
@ -1723,6 +1726,9 @@ static int get_any_page(struct page *page, unsigned long pfn, int flags)
|
||||
{
|
||||
int ret = __get_any_page(page, pfn, flags);
|
||||
|
||||
if (ret == -EBUSY)
|
||||
ret = __get_any_page(page, pfn, flags);
|
||||
|
||||
if (ret == 1 && !PageHuge(page) &&
|
||||
!PageLRU(page) && !__PageMovable(page)) {
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user