From: Liu Shixin liushixin2@huawei.com
hulk inclusion category: bugfix bugzilla: 46904, https://gitee.com/openeuler/kernel/issues/I6GSKP CVE: NA
--------------------------------
For a hwpoison hugetlb page, the page will be freed firstly. If succeed, it will be dissolved and released to buddy system, then isolate the hwpoison page.
For a hwpoison hugepage belong to dynamic hugetlb, we isolate the hugepage without dissolve it. Add a check in free_huge_page_to_dhugetlb_pool() to isolate the hwpoison hugepage directly. And keep HUGETLB_PAGE_DTOR after free to ensure the PageHuge() check return true in dissolve_free_huge_page().
Fixes: 0f0535e57da("dhugetlb: skip dissolve hugepage belonging to dynamic hugetlb") Signed-off-by: Liu Shixin liushixin2@huawei.com Reviewed-by: Kefeng Wang wangkefeng.wang@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- mm/hugetlb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index ed89df6fc5de..9f974270c84d 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1348,8 +1348,9 @@ static void free_huge_page_to_dhugetlb_pool(struct page *page, }
spin_lock(&hpool->lock); + if (PageHWPoison(page)) + goto out; ClearPagePool(page); - set_compound_page_dtor(page, NULL_COMPOUND_DTOR); if (!hstate_is_gigantic(h)) { list_add(&page->lru, &hpool->dhugetlb_2M_freelists); hpool->free_reserved_2M++; @@ -1375,6 +1376,7 @@ static void free_huge_page_to_dhugetlb_pool(struct page *page, trace_dhugetlb_alloc_free(hpool, page, hpool->free_reserved_1G, DHUGETLB_FREE_1G); } +out: spin_unlock(&hpool->lock); dhugetlb_pool_put(hpool); }