mm, hwpoison, hugetlb: Check hugetlb head page hwpoison flag when unpoison page
Subsystems (2)
PATCH 1/1 mm, hwpoison, hugetlb: Check hugetlb head page hwpoison flag when unpoison page
When software-poison a huge page, if dissolve_free_huge_page() failed, the huge page will be added to hugepage_freelists. In this case, the head page will hold the hwpoison flag, but the real poisoned tail page hwpoison flag is not set, this will cause unpoison_memory() fail to unpoison the previously poisoned page.
So add a check on hugetlb head page, and also need to ensure the previously poisoned tail page in huge page raw_hwp_list.
--- mm/memory-failure.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
mm/memory-failure.c +23 -1
@@ -2293,6 +2293,28 @@ core_initcall(memory_failure_init);pr_info (fmt, pfn); \ }) +static bool hugetlb_page_head_poison (struct page *hpage,struct page *page) +{ +struct llist_head *head; +struct llist_node *t, *tnode; +struct raw_hwp_page *p; + +if (PageHuge (page) &&PageHWPoison (hpage) &&HPageFreed (hpage)) +return false; + +if (HPageRawHwpUnreliable (hpage)) +return false; + + head =raw_hwp_list_head (hpage); +llist_for_each_safe (tnode, t, head->first) { + p = container_of(tnode, struct raw_hwp_page, node); +if (p->page == page) +return true; + } + +return false; +} +/** * unpoison_memory - Unpoison a previously poisoned page * @pfn: Page number of the to be unpoisoned page
@@ -2330,7 +2352,7 @@ int unpoison_memory(unsigned long pfn) goto unlock_mutex; } -if (!PageHWPoison (p)) { +if (!PageHWPoison (p) && !hugetlb_page_head_poison (page, p)) {unpoison_pr_info ("Unpoison: Page was already unpoisoned %#lx\n" , pfn, &unpoison_rs); goto unlock_mutex;
Signature · 1 line
2.27.0
Sorry, wrong patch, please ignore this email.
________________________________________
发件人: 罗飞
发送时间: 2022年8月4日 19:33:08
收件人: [email protected]; [email protected]
抄送: [email protected]; [email protected]; [email protected]; 罗飞 主题: [PATCH] mm, hwpoison, hugetlb: Check hugetlb head page hwpoison flag when unpoison page
When software-poison a huge page, if dissolve_free_huge_page() failed, the huge page will be added to hugepage_freelists. In this case, the head page will hold the hwpoison flag, but the real poisoned tail page hwpoison flag is not set, this will cause unpoison_memory() fail to unpoison the previously poisoned page.
So add a check on hugetlb head page, and also need to ensure the previously poisoned tail page in huge page raw_hwp_list.
--- mm/memory-failure.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
mm/memory-failure.c +23 -1
@@ -2293,6 +2293,28 @@ core_initcall(memory_failure_init);pr_info (fmt, pfn); \ }) +static bool hugetlb_page_head_poison (struct page *hpage,struct page *page) +{ +struct llist_head *head; +struct llist_node *t, *tnode; +struct raw_hwp_page *p; + +if (PageHuge (page) &&PageHWPoison (hpage) &&HPageFreed (hpage)) +return false; + +if (HPageRawHwpUnreliable (hpage)) +return false; + + head =raw_hwp_list_head (hpage); +llist_for_each_safe (tnode, t, head->first) { + p = container_of(tnode, struct raw_hwp_page, node); +if (p->page == page) +return true; + } + +return false; +} +/** * unpoison_memory - Unpoison a previously poisoned page * @pfn: Page number of the to be unpoisoned page
@@ -2330,7 +2352,7 @@ int unpoison_memory(unsigned long pfn) goto unlock_mutex; } -if (!PageHWPoison (p)) { +if (!PageHWPoison (p) && !hugetlb_page_head_poison (page, p)) {unpoison_pr_info ("Unpoison: Page was already unpoisoned %#lx\n" , pfn, &unpoison_rs); goto unlock_mutex;
--
2.27.0