From: Naoya Horiguchi <naoya.horiguchi@xxxxxxx> HWPoisoned page is not supposed to be accessed once marked, but currently such accesses can happen during memory hotremove because do_migrate_range() can be called before dissolve_free_huge_pages() is called. Move dissolve_free_huge_pages() before scan_movable_pages(). Recently delayed dissolve has been implemented, so the dissolving can turn a hwpoisoned hugepage into 4kB hwpoison page, which memory hotplug can handle safely. Reported-by: Miaohe Lin <linmiaohe@xxxxxxxxxx> Signed-off-by: Naoya Horiguchi <naoya.horiguchi@xxxxxxx> --- mm/memory_hotplug.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index fad6d1f2262a..c24735d63b25 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1880,6 +1880,17 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages, cond_resched(); + /* + * Dissolve free hugepages in the memory block before doing + * offlining actually in order to make hugetlbfs's object + * counting consistent. + */ + ret = dissolve_free_huge_pages(start_pfn, end_pfn); + if (ret) { + reason = "failure to dissolve huge pages"; + goto failed_removal_isolated; + } + ret = scan_movable_pages(pfn, end_pfn, &pfn); if (!ret) { /* @@ -1895,17 +1906,6 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages, goto failed_removal_isolated; } - /* - * Dissolve free hugepages in the memory block before doing - * offlining actually in order to make hugetlbfs's object - * counting consistent. - */ - ret = dissolve_free_huge_pages(start_pfn, end_pfn); - if (ret) { - reason = "failure to dissolve huge pages"; - goto failed_removal_isolated; - } - ret = test_pages_isolated(start_pfn, end_pfn, MEMORY_OFFLINE); } while (ret); -- 2.25.1