diff mbox series

mm/hwpoison: dissolve error hugepages of file mapping

Message ID 20210715150852.1655-1-wangbin224@huawei.com (mailing list archive)
State New
Headers show
Series mm/hwpoison: dissolve error hugepages of file mapping | expand

Commit Message

Bin Wang July 15, 2021, 3:08 p.m. UTC
We handle error on hugetlb file with hugetlbfs_error_remove_page(),
which removes the error hugepages from page cache. And with the
HWPoison flag in head page, it is safe to free the error hugepages
and dissolve it.

Fixes: 78bb920344b8a ("mm: hwpoison: dissolve in-use hugepage in unrecoverable memory error")
Signed-off-by: Bin Wang <wangbin224@huawei.com>
---
 mm/memory-failure.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Matthew Wilcox July 15, 2021, 3:22 p.m. UTC | #1
On Thu, Jul 15, 2021 at 11:08:52PM +0800, Bin Wang wrote:
> We handle error on hugetlb file with hugetlbfs_error_remove_page(),
> which removes the error hugepages from page cache. And with the
> HWPoison flag in head page, it is safe to free the error hugepages
> and dissolve it.

How is that safe?  If you're going to dissolve the huge page, you
need to figure out which subpage needs to have the HWPoison flag set.
Bin Wang July 16, 2021, 1 a.m. UTC | #2
Hi Matthew,

On Thu, 15 Jul 2021 at 16:22:40 +0100, Matthew Wilcox wrote:
> How is that safe?  If you're going to dissolve the huge page, you
> need to figure out which subpage needs to have the HWPoison flag set.

Thanks for your review. The p that we pass to the __page_handle_poison()
is the error subpage. And we will move the HWPoison flag to subpage in
the dissolve_free_huge_page():

if (PageHWPoison(head) && page != head) {
	SetPageHWPoison(page);
	ClearPageHWPoison(head);
}

Thanks,
Bin Wang
diff mbox series

Patch

diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index eefd823deb67..6a3c46b601ef 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -988,6 +988,13 @@  static int me_huge_page(struct page *p, unsigned long pfn)
 	if (mapping) {
 		res = truncate_error_page(hpage, pfn, mapping);
 		unlock_page(hpage);
+		if (ret == MF_RECOVERED) {
+			put_page(hpage);
+			if (__page_handle_poison(p))
+				page_ref_inc(p);
+			else
+				ret = MF_FAILED;
+		}
 	} else {
 		res = MF_FAILED;
 		unlock_page(hpage);