Message ID | 20240515023607.870022-1-linmiaohe@huawei.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [v2] mm/huge_memory: don't unpoison huge_zero_folio | expand |
On 15.05.24 04:36, Miaohe Lin wrote: > When I did memory failure tests recently, below panic occurs: > > kernel BUG at include/linux/mm.h:1135! > invalid opcode: 0000 [#1] PREEMPT SMP NOPTI > CPU: 9 PID: 137 Comm: kswapd1 Not tainted 6.9.0-rc4-00491-gd5ce28f156fe-dirty #14 > RIP: 0010:shrink_huge_zero_page_scan+0x168/0x1a0 > RSP: 0018:ffff9933c6c57bd0 EFLAGS: 00000246 > RAX: 000000000000003e RBX: 0000000000000000 RCX: ffff88f61fc5c9c8 > RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff88f61fc5c9c0 > RBP: ffffcd7c446b0000 R08: ffffffff9a9405f0 R09: 0000000000005492 > R10: 00000000000030ea R11: ffffffff9a9405f0 R12: 0000000000000000 > R13: 0000000000000000 R14: 0000000000000000 R15: ffff88e703c4ac00 > FS: 0000000000000000(0000) GS:ffff88f61fc40000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 000055f4da6e9878 CR3: 0000000c71048000 CR4: 00000000000006f0 > Call Trace: > <TASK> > do_shrink_slab+0x14f/0x6a0 > shrink_slab+0xca/0x8c0 > shrink_node+0x2d0/0x7d0 > balance_pgdat+0x33a/0x720 > kswapd+0x1f3/0x410 > kthread+0xd5/0x100 > ret_from_fork+0x2f/0x50 > ret_from_fork_asm+0x1a/0x30 > </TASK> > Modules linked in: mce_inject hwpoison_inject > ---[ end trace 0000000000000000 ]--- > RIP: 0010:shrink_huge_zero_page_scan+0x168/0x1a0 > RSP: 0018:ffff9933c6c57bd0 EFLAGS: 00000246 > RAX: 000000000000003e RBX: 0000000000000000 RCX: ffff88f61fc5c9c8 > RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff88f61fc5c9c0 > RBP: ffffcd7c446b0000 R08: ffffffff9a9405f0 R09: 0000000000005492 > R10: 00000000000030ea R11: ffffffff9a9405f0 R12: 0000000000000000 > R13: 0000000000000000 R14: 0000000000000000 R15: ffff88e703c4ac00 > FS: 0000000000000000(0000) GS:ffff88f61fc40000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 000055f4da6e9878 CR3: 0000000c71048000 CR4: 00000000000006f0 > > The root cause is that HWPoison flag will be set for huge_zero_folio > without increasing the folio refcnt. But then unpoison_memory() will > decrease the folio refcnt unexpectly as it appears like a successfully > hwpoisoned folio leading to VM_BUG_ON_PAGE(page_ref_count(page) == 0) > when releasing huge_zero_folio. > > Skip unpoisoning huge_zero_folio in unpoison_memory() to fix this issue. > We're not prepared to unpoison huge_zero_folio yet. > > Fixes: 478d134e9506 ("mm/huge_memory: do not overkill when splitting huge_zero_page") > Signed-off-by: Miaohe Lin <linmiaohe@huawei.com> > Cc: <stable@vger.kernel.org> > --- > v2: > Change to simply check for the huge zero page. Thanks. > --- > mm/memory-failure.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > index 16ada4fb02b7..68bc8d7ff53d 100644 > --- a/mm/memory-failure.c > +++ b/mm/memory-failure.c > @@ -2558,6 +2558,12 @@ int unpoison_memory(unsigned long pfn) > goto unlock_mutex; > } > > + if (is_huge_zero_folio(folio)) { > + unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", > + pfn, &unpoison_rs); > + goto unlock_mutex; > + } > + > if (folio_test_slab(folio) || folio_test_pgtable(folio) || > folio_test_reserved(folio) || folio_test_offline(folio)) > goto unlock_mutex; Acked-by: David Hildenbrand <david@redhat.com>
On Tue, May 14, 2024 at 8:39 PM Miaohe Lin <linmiaohe@huawei.com> wrote: > > When I did memory failure tests recently, below panic occurs: > > kernel BUG at include/linux/mm.h:1135! > invalid opcode: 0000 [#1] PREEMPT SMP NOPTI > CPU: 9 PID: 137 Comm: kswapd1 Not tainted 6.9.0-rc4-00491-gd5ce28f156fe-dirty #14 > RIP: 0010:shrink_huge_zero_page_scan+0x168/0x1a0 > RSP: 0018:ffff9933c6c57bd0 EFLAGS: 00000246 > RAX: 000000000000003e RBX: 0000000000000000 RCX: ffff88f61fc5c9c8 > RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff88f61fc5c9c0 > RBP: ffffcd7c446b0000 R08: ffffffff9a9405f0 R09: 0000000000005492 > R10: 00000000000030ea R11: ffffffff9a9405f0 R12: 0000000000000000 > R13: 0000000000000000 R14: 0000000000000000 R15: ffff88e703c4ac00 > FS: 0000000000000000(0000) GS:ffff88f61fc40000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 000055f4da6e9878 CR3: 0000000c71048000 CR4: 00000000000006f0 > Call Trace: > <TASK> > do_shrink_slab+0x14f/0x6a0 > shrink_slab+0xca/0x8c0 > shrink_node+0x2d0/0x7d0 > balance_pgdat+0x33a/0x720 > kswapd+0x1f3/0x410 > kthread+0xd5/0x100 > ret_from_fork+0x2f/0x50 > ret_from_fork_asm+0x1a/0x30 > </TASK> > Modules linked in: mce_inject hwpoison_inject > ---[ end trace 0000000000000000 ]--- > RIP: 0010:shrink_huge_zero_page_scan+0x168/0x1a0 > RSP: 0018:ffff9933c6c57bd0 EFLAGS: 00000246 > RAX: 000000000000003e RBX: 0000000000000000 RCX: ffff88f61fc5c9c8 > RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff88f61fc5c9c0 > RBP: ffffcd7c446b0000 R08: ffffffff9a9405f0 R09: 0000000000005492 > R10: 00000000000030ea R11: ffffffff9a9405f0 R12: 0000000000000000 > R13: 0000000000000000 R14: 0000000000000000 R15: ffff88e703c4ac00 > FS: 0000000000000000(0000) GS:ffff88f61fc40000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 000055f4da6e9878 CR3: 0000000c71048000 CR4: 00000000000006f0 > > The root cause is that HWPoison flag will be set for huge_zero_folio > without increasing the folio refcnt. But then unpoison_memory() will > decrease the folio refcnt unexpectly as it appears like a successfully > hwpoisoned folio leading to VM_BUG_ON_PAGE(page_ref_count(page) == 0) > when releasing huge_zero_folio. > > Skip unpoisoning huge_zero_folio in unpoison_memory() to fix this issue. > We're not prepared to unpoison huge_zero_folio yet. > > Fixes: 478d134e9506 ("mm/huge_memory: do not overkill when splitting huge_zero_page") > Signed-off-by: Miaohe Lin <linmiaohe@huawei.com> > Cc: <stable@vger.kernel.org> Reviewed-by: Yang Shi <shy828301@gmail.com> > --- > v2: > Change to simply check for the huge zero page. Thanks. > --- > mm/memory-failure.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > index 16ada4fb02b7..68bc8d7ff53d 100644 > --- a/mm/memory-failure.c > +++ b/mm/memory-failure.c > @@ -2558,6 +2558,12 @@ int unpoison_memory(unsigned long pfn) > goto unlock_mutex; > } > > + if (is_huge_zero_folio(folio)) { > + unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", > + pfn, &unpoison_rs); > + goto unlock_mutex; > + } > + > if (folio_test_slab(folio) || folio_test_pgtable(folio) || > folio_test_reserved(folio) || folio_test_offline(folio)) > goto unlock_mutex; > -- > 2.33.0 >
On Wed, May 15, 2024 at 05:55:39PM +0200, David Hildenbrand wrote: > > + if (is_huge_zero_folio(folio)) { > > + unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", > > + pfn, &unpoison_rs); > > + goto unlock_mutex; > > + } > > + Sorry for spamming your reply David, but for some unknown reason I am not able to find the original patch in my mailbox, in none of the two accountes I am subscribed, so I guess I will have to reply here. Just two things 1) We do not care if someone grabs a refcount for huge_zero_folio, because since it is not supported anyway the outcome will not change. Also, AFAIK, there is no chance we can unpoison that folio. Therefore, I would just lift the check two blocks and place it right after the hw_memory_failure check. 2) The whole thing is unsupported, but you will return -EBUSY while you should be returning -EOPNOTSUPP AFAICS. with that you can add: Reviewed-by: Oscar Salvador <osalvador@suse.de>
On 2024/5/16 16:26, Oscar Salvador wrote: > On Wed, May 15, 2024 at 05:55:39PM +0200, David Hildenbrand wrote: >>> + if (is_huge_zero_folio(folio)) { >>> + unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", >>> + pfn, &unpoison_rs); >>> + goto unlock_mutex; >>> + } >>> + > > Sorry for spamming your reply David, but for some unknown reason I am not able > to find the original patch in my mailbox, in none of the two accountes I am > subscribed, so I guess I will have to reply here. > > Just two things > > 1) We do not care if someone grabs a refcount for huge_zero_folio, > because since it is not supported anyway the outcome will not change. > Also, AFAIK, there is no chance we can unpoison that folio. > Therefore, I would just lift the check two blocks and place it right after > the hw_memory_failure check. > > 2) The whole thing is unsupported, but you will return -EBUSY while you > should be returning -EOPNOTSUPP AFAICS. > Thanks for your comment. Do you mean something like below? diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 16ada4fb02b7..a9fe9eda593f 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -2546,6 +2546,13 @@ int unpoison_memory(unsigned long pfn) goto unlock_mutex; } + if (is_huge_zero_folio(folio)) { + unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", + pfn, &unpoison_rs); + ret = -EOPNOTSUPP; + goto unlock_mutex; + } + if (!PageHWPoison(p)) { unpoison_pr_info("Unpoison: Page was already unpoisoned %#lx\n", pfn, &unpoison_rs); Thanks. . > with that you can add: > > Reviewed-by: Oscar Salvador <osalvador@suse.de> > > >
On Thu, May 16, 2024 at 04:45:22PM +0800, Miaohe Lin wrote: > Thanks for your comment. Do you mean something like below? > > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > index 16ada4fb02b7..a9fe9eda593f 100644 > --- a/mm/memory-failure.c > +++ b/mm/memory-failure.c > @@ -2546,6 +2546,13 @@ int unpoison_memory(unsigned long pfn) > goto unlock_mutex; > } > > + if (is_huge_zero_folio(folio)) { > + unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", > + pfn, &unpoison_rs); > + ret = -EOPNOTSUPP; > + goto unlock_mutex; > + } > + > if (!PageHWPoison(p)) { > unpoison_pr_info("Unpoison: Page was already unpoisoned %#lx\n", > pfn, &unpoison_rs); Yes, something like that makes much more sense to me. Thanks
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 16ada4fb02b7..68bc8d7ff53d 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -2558,6 +2558,12 @@ int unpoison_memory(unsigned long pfn) goto unlock_mutex; } + if (is_huge_zero_folio(folio)) { + unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n", + pfn, &unpoison_rs); + goto unlock_mutex; + } + if (folio_test_slab(folio) || folio_test_pgtable(folio) || folio_test_reserved(folio) || folio_test_offline(folio)) goto unlock_mutex;
When I did memory failure tests recently, below panic occurs: kernel BUG at include/linux/mm.h:1135! invalid opcode: 0000 [#1] PREEMPT SMP NOPTI CPU: 9 PID: 137 Comm: kswapd1 Not tainted 6.9.0-rc4-00491-gd5ce28f156fe-dirty #14 RIP: 0010:shrink_huge_zero_page_scan+0x168/0x1a0 RSP: 0018:ffff9933c6c57bd0 EFLAGS: 00000246 RAX: 000000000000003e RBX: 0000000000000000 RCX: ffff88f61fc5c9c8 RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff88f61fc5c9c0 RBP: ffffcd7c446b0000 R08: ffffffff9a9405f0 R09: 0000000000005492 R10: 00000000000030ea R11: ffffffff9a9405f0 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: ffff88e703c4ac00 FS: 0000000000000000(0000) GS:ffff88f61fc40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055f4da6e9878 CR3: 0000000c71048000 CR4: 00000000000006f0 Call Trace: <TASK> do_shrink_slab+0x14f/0x6a0 shrink_slab+0xca/0x8c0 shrink_node+0x2d0/0x7d0 balance_pgdat+0x33a/0x720 kswapd+0x1f3/0x410 kthread+0xd5/0x100 ret_from_fork+0x2f/0x50 ret_from_fork_asm+0x1a/0x30 </TASK> Modules linked in: mce_inject hwpoison_inject ---[ end trace 0000000000000000 ]--- RIP: 0010:shrink_huge_zero_page_scan+0x168/0x1a0 RSP: 0018:ffff9933c6c57bd0 EFLAGS: 00000246 RAX: 000000000000003e RBX: 0000000000000000 RCX: ffff88f61fc5c9c8 RDX: 0000000000000000 RSI: 0000000000000027 RDI: ffff88f61fc5c9c0 RBP: ffffcd7c446b0000 R08: ffffffff9a9405f0 R09: 0000000000005492 R10: 00000000000030ea R11: ffffffff9a9405f0 R12: 0000000000000000 R13: 0000000000000000 R14: 0000000000000000 R15: ffff88e703c4ac00 FS: 0000000000000000(0000) GS:ffff88f61fc40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055f4da6e9878 CR3: 0000000c71048000 CR4: 00000000000006f0 The root cause is that HWPoison flag will be set for huge_zero_folio without increasing the folio refcnt. But then unpoison_memory() will decrease the folio refcnt unexpectly as it appears like a successfully hwpoisoned folio leading to VM_BUG_ON_PAGE(page_ref_count(page) == 0) when releasing huge_zero_folio. Skip unpoisoning huge_zero_folio in unpoison_memory() to fix this issue. We're not prepared to unpoison huge_zero_folio yet. Fixes: 478d134e9506 ("mm/huge_memory: do not overkill when splitting huge_zero_page") Signed-off-by: Miaohe Lin <linmiaohe@huawei.com> Cc: <stable@vger.kernel.org> --- v2: Change to simply check for the huge zero page. Thanks. --- mm/memory-failure.c | 6 ++++++ 1 file changed, 6 insertions(+)