* [PATCH v3 0/3] mm: memory_failure: unmap poisoned filio during migrate properly
@ 2025-02-17 1:43 Wupeng Ma
2025-02-17 1:43 ` [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio Wupeng Ma
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Wupeng Ma @ 2025-02-17 1:43 UTC (permalink / raw)
To: akpm, david, osalvador, nao.horiguchi, linmiaohe, mhocko
Cc: mawupeng1, linux-mm, linux-kernel
From: Ma Wupeng <mawupeng1@huawei.com>
Fix two bugs during migrate folio if folio is poisoned.
Changelog since v2:
- re-order patches
- fix compile errors
- modify patch #2 as suggested
Changelog since v1:
- update ttu flag inside unmap_poisoned_folio.
- check folio ref count before unmap HWpoisoned folio.
Ma Wupeng (3):
mm: memory-failure: update ttu flag inside unmap_poisoned_folio
mm: memory-hotplug: check folio ref count first in do_migrate_range
hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio
mm/internal.h | 5 ++--
mm/memory-failure.c | 61 +++++++++++++++++++++++----------------------
mm/memory_hotplug.c | 26 +++++++++----------
3 files changed, 46 insertions(+), 46 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio 2025-02-17 1:43 [PATCH v3 0/3] mm: memory_failure: unmap poisoned filio during migrate properly Wupeng Ma @ 2025-02-17 1:43 ` Wupeng Ma 2025-02-19 2:50 ` Miaohe Lin 2025-03-19 17:21 ` Arthur Marsh 2025-02-17 1:43 ` [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range Wupeng Ma 2025-02-17 1:43 ` [PATCH v3 3/3] hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio Wupeng Ma 2 siblings, 2 replies; 13+ messages in thread From: Wupeng Ma @ 2025-02-17 1:43 UTC (permalink / raw) To: akpm, david, osalvador, nao.horiguchi, linmiaohe, mhocko Cc: mawupeng1, linux-mm, linux-kernel From: Ma Wupeng <mawupeng1@huawei.com> Commit 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON") introduce TTU_HWPOISON to replace TTU_IGNORE_HWPOISON in order to stop send SIGBUS signal when accessing an error page after a memory error on a clean folio. However during page migration, anon folio must be set with TTU_HWPOISON during unmap_*(). For pagecache we need some policy just like the one in hwpoison_user_mappings to set this flag. So move this policy from hwpoison_user_mappings to unmap_poisoned_folio to handle this warning properly. Warning will be produced during unamp poison folio with the following log: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 365 at mm/rmap.c:1847 try_to_unmap_one+0x8fc/0xd3c Modules linked in: CPU: 1 UID: 0 PID: 365 Comm: bash Tainted: G W 6.13.0-rc1-00018-gacdb4bbda7ab #42 Tainted: [W]=WARN Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : try_to_unmap_one+0x8fc/0xd3c lr : try_to_unmap_one+0x3dc/0xd3c Call trace: try_to_unmap_one+0x8fc/0xd3c (P) try_to_unmap_one+0x3dc/0xd3c (L) rmap_walk_anon+0xdc/0x1f8 rmap_walk+0x3c/0x58 try_to_unmap+0x88/0x90 unmap_poisoned_folio+0x30/0xa8 do_migrate_range+0x4a0/0x568 offline_pages+0x5a4/0x670 memory_block_action+0x17c/0x374 memory_subsys_offline+0x3c/0x78 device_offline+0xa4/0xd0 state_store+0x8c/0xf0 dev_attr_store+0x18/0x2c sysfs_kf_write+0x44/0x54 kernfs_fop_write_iter+0x118/0x1a8 vfs_write+0x3a8/0x4bc ksys_write+0x6c/0xf8 __arm64_sys_write+0x1c/0x28 invoke_syscall+0x44/0x100 el0_svc_common.constprop.0+0x40/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x30/0xd0 el0t_64_sync_handler+0xc8/0xcc el0t_64_sync+0x198/0x19c ---[ end trace 0000000000000000 ]--- Fixes: 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON") Suggested-by: David Hildenbrand <david@redhat.com> Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> Acked-by: David Hildenbrand <david@redhat.com> --- mm/internal.h | 5 ++-- mm/memory-failure.c | 61 +++++++++++++++++++++++---------------------- mm/memory_hotplug.c | 3 ++- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index 9826f7dce607..c9186ca8d7c2 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1102,7 +1102,7 @@ static inline int find_next_best_node(int node, nodemask_t *used_node_mask) * mm/memory-failure.c */ #ifdef CONFIG_MEMORY_FAILURE -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu); +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill); void shake_folio(struct folio *folio); extern int hwpoison_filter(struct page *p); @@ -1125,8 +1125,9 @@ unsigned long page_mapped_in_vma(const struct page *page, struct vm_area_struct *vma); #else -static inline void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) +static inline int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) { + return -EBUSY; } #endif diff --git a/mm/memory-failure.c b/mm/memory-failure.c index a7b8ccd29b6f..b5212b6e330a 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1556,8 +1556,34 @@ static int get_hwpoison_page(struct page *p, unsigned long flags) return ret; } -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) { + enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC | TTU_HWPOISON; + struct address_space *mapping; + + if (folio_test_swapcache(folio)) { + pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); + ttu &= ~TTU_HWPOISON; + } + + /* + * Propagate the dirty bit from PTEs to struct page first, because we + * need this to decide if we should kill or just drop the page. + * XXX: the dirty test could be racy: set_page_dirty() may not always + * be called inside page lock (it's recommended but not enforced). + */ + mapping = folio_mapping(folio); + if (!must_kill && !folio_test_dirty(folio) && mapping && + mapping_can_writeback(mapping)) { + if (folio_mkclean(folio)) { + folio_set_dirty(folio); + } else { + ttu &= ~TTU_HWPOISON; + pr_info("%#lx: corrupted page was clean: dropped without side effects\n", + pfn); + } + } + if (folio_test_hugetlb(folio) && !folio_test_anon(folio)) { struct address_space *mapping; @@ -1572,7 +1598,7 @@ void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) if (!mapping) { pr_info("%#lx: could not lock mapping for mapped hugetlb folio\n", folio_pfn(folio)); - return; + return -EBUSY; } try_to_unmap(folio, ttu|TTU_RMAP_LOCKED); @@ -1580,6 +1606,8 @@ void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) } else { try_to_unmap(folio, ttu); } + + return folio_mapped(folio) ? -EBUSY : 0; } /* @@ -1589,8 +1617,6 @@ void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) static bool hwpoison_user_mappings(struct folio *folio, struct page *p, unsigned long pfn, int flags) { - enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC | TTU_HWPOISON; - struct address_space *mapping; LIST_HEAD(tokill); bool unmap_success; int forcekill; @@ -1613,29 +1639,6 @@ static bool hwpoison_user_mappings(struct folio *folio, struct page *p, if (!folio_mapped(folio)) return true; - if (folio_test_swapcache(folio)) { - pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); - ttu &= ~TTU_HWPOISON; - } - - /* - * Propagate the dirty bit from PTEs to struct page first, because we - * need this to decide if we should kill or just drop the page. - * XXX: the dirty test could be racy: set_page_dirty() may not always - * be called inside page lock (it's recommended but not enforced). - */ - mapping = folio_mapping(folio); - if (!(flags & MF_MUST_KILL) && !folio_test_dirty(folio) && mapping && - mapping_can_writeback(mapping)) { - if (folio_mkclean(folio)) { - folio_set_dirty(folio); - } else { - ttu &= ~TTU_HWPOISON; - pr_info("%#lx: corrupted page was clean: dropped without side effects\n", - pfn); - } - } - /* * First collect all the processes that have the page * mapped in dirty form. This has to be done before try_to_unmap, @@ -1643,9 +1646,7 @@ static bool hwpoison_user_mappings(struct folio *folio, struct page *p, */ collect_procs(folio, p, &tokill, flags & MF_ACTION_REQUIRED); - unmap_poisoned_folio(folio, ttu); - - unmap_success = !folio_mapped(folio); + unmap_success = !unmap_poisoned_folio(folio, pfn, flags & MF_MUST_KILL); if (!unmap_success) pr_err("%#lx: failed to unmap page (folio mapcount=%d)\n", pfn, folio_mapcount(folio)); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index c43b4e7fb298..3de661e57e92 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1806,7 +1806,8 @@ static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) if (WARN_ON(folio_test_lru(folio))) folio_isolate_lru(folio); if (folio_mapped(folio)) - unmap_poisoned_folio(folio, TTU_IGNORE_MLOCK); + unmap_poisoned_folio(folio, pfn, false); + continue; } -- 2.43.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio 2025-02-17 1:43 ` [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio Wupeng Ma @ 2025-02-19 2:50 ` Miaohe Lin 2025-02-19 3:34 ` mawupeng 2025-02-19 6:06 ` [PATCH v3] " Wupeng Ma 2025-03-19 17:21 ` Arthur Marsh 1 sibling, 2 replies; 13+ messages in thread From: Miaohe Lin @ 2025-02-19 2:50 UTC (permalink / raw) To: Wupeng Ma Cc: linux-mm, linux-kernel, akpm, david, osalvador, nao.horiguchi, mhocko On 2025/2/17 9:43, Wupeng Ma wrote: > From: Ma Wupeng <mawupeng1@huawei.com> > > Commit 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to > TTU_HWPOISON") introduce TTU_HWPOISON to replace TTU_IGNORE_HWPOISON > in order to stop send SIGBUS signal when accessing an error page after > a memory error on a clean folio. However during page migration, anon > folio must be set with TTU_HWPOISON during unmap_*(). For pagecache > we need some policy just like the one in hwpoison_user_mappings to > set this flag. So move this policy from hwpoison_user_mappings to > unmap_poisoned_folio to handle this warning properly. > > Warning will be produced during unamp poison folio with the following log: > > ------------[ cut here ]------------ > WARNING: CPU: 1 PID: 365 at mm/rmap.c:1847 try_to_unmap_one+0x8fc/0xd3c > Modules linked in: > CPU: 1 UID: 0 PID: 365 Comm: bash Tainted: G W 6.13.0-rc1-00018-gacdb4bbda7ab #42 > Tainted: [W]=WARN > Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 > pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) > pc : try_to_unmap_one+0x8fc/0xd3c > lr : try_to_unmap_one+0x3dc/0xd3c > Call trace: > try_to_unmap_one+0x8fc/0xd3c (P) > try_to_unmap_one+0x3dc/0xd3c (L) > rmap_walk_anon+0xdc/0x1f8 > rmap_walk+0x3c/0x58 > try_to_unmap+0x88/0x90 > unmap_poisoned_folio+0x30/0xa8 > do_migrate_range+0x4a0/0x568 > offline_pages+0x5a4/0x670 > memory_block_action+0x17c/0x374 > memory_subsys_offline+0x3c/0x78 > device_offline+0xa4/0xd0 > state_store+0x8c/0xf0 > dev_attr_store+0x18/0x2c > sysfs_kf_write+0x44/0x54 > kernfs_fop_write_iter+0x118/0x1a8 > vfs_write+0x3a8/0x4bc > ksys_write+0x6c/0xf8 > __arm64_sys_write+0x1c/0x28 > invoke_syscall+0x44/0x100 > el0_svc_common.constprop.0+0x40/0xe0 > do_el0_svc+0x1c/0x28 > el0_svc+0x30/0xd0 > el0t_64_sync_handler+0xc8/0xcc > el0t_64_sync+0x198/0x19c > ---[ end trace 0000000000000000 ]--- > > Fixes: 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON") > Suggested-by: David Hildenbrand <david@redhat.com> > Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> > Acked-by: David Hildenbrand <david@redhat.com> Thanks. LGTM. One nit below. Acked-by: Miaohe Lin <linmiaohe@huawei.com> > --- > mm/internal.h | 5 ++-- > mm/memory-failure.c | 61 +++++++++++++++++++++++---------------------- > mm/memory_hotplug.c | 3 ++- > 3 files changed, 36 insertions(+), 33 deletions(-) > > diff --git a/mm/internal.h b/mm/internal.h > index 9826f7dce607..c9186ca8d7c2 100644 > --- a/mm/internal.h > +++ b/mm/internal.h > @@ -1102,7 +1102,7 @@ static inline int find_next_best_node(int node, nodemask_t *used_node_mask) > * mm/memory-failure.c > */ > #ifdef CONFIG_MEMORY_FAILURE > -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu); > +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill); > void shake_folio(struct folio *folio); > extern int hwpoison_filter(struct page *p); > > @@ -1125,8 +1125,9 @@ unsigned long page_mapped_in_vma(const struct page *page, > struct vm_area_struct *vma); > > #else > -static inline void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) > +static inline int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) > { > + return -EBUSY; > } > #endif > > diff --git a/mm/memory-failure.c b/mm/memory-failure.c > index a7b8ccd29b6f..b5212b6e330a 100644 > --- a/mm/memory-failure.c > +++ b/mm/memory-failure.c > @@ -1556,8 +1556,34 @@ static int get_hwpoison_page(struct page *p, unsigned long flags) > return ret; > } > > -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) > +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) > { > + enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC | TTU_HWPOISON; > + struct address_space *mapping; > + > + if (folio_test_swapcache(folio)) { > + pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); > + ttu &= ~TTU_HWPOISON; > + } > + > + /* > + * Propagate the dirty bit from PTEs to struct page first, because we > + * need this to decide if we should kill or just drop the page. > + * XXX: the dirty test could be racy: set_page_dirty() may not always > + * be called inside page lock (it's recommended but not enforced). > + */ > + mapping = folio_mapping(folio); > + if (!must_kill && !folio_test_dirty(folio) && mapping && > + mapping_can_writeback(mapping)) { > + if (folio_mkclean(folio)) { > + folio_set_dirty(folio); > + } else { > + ttu &= ~TTU_HWPOISON; > + pr_info("%#lx: corrupted page was clean: dropped without side effects\n", > + pfn); > + } > + } > + > if (folio_test_hugetlb(folio) && !folio_test_anon(folio)) { > struct address_space *mapping; This mapping can be removed as we have already defined one above. But this is trivial. Thanks. . ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio 2025-02-19 2:50 ` Miaohe Lin @ 2025-02-19 3:34 ` mawupeng 2025-02-19 6:06 ` [PATCH v3] " Wupeng Ma 1 sibling, 0 replies; 13+ messages in thread From: mawupeng @ 2025-02-19 3:34 UTC (permalink / raw) To: linmiaohe Cc: mawupeng1, linux-mm, linux-kernel, akpm, david, osalvador, nao.horiguchi, mhocko On 2025/2/19 10:50, Miaohe Lin wrote: > On 2025/2/17 9:43, Wupeng Ma wrote: >> From: Ma Wupeng <mawupeng1@huawei.com> >> >> Commit 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to >> TTU_HWPOISON") introduce TTU_HWPOISON to replace TTU_IGNORE_HWPOISON >> in order to stop send SIGBUS signal when accessing an error page after >> a memory error on a clean folio. However during page migration, anon >> folio must be set with TTU_HWPOISON during unmap_*(). For pagecache >> we need some policy just like the one in hwpoison_user_mappings to >> set this flag. So move this policy from hwpoison_user_mappings to >> unmap_poisoned_folio to handle this warning properly. >> >> Warning will be produced during unamp poison folio with the following log: >> >> ------------[ cut here ]------------ >> WARNING: CPU: 1 PID: 365 at mm/rmap.c:1847 try_to_unmap_one+0x8fc/0xd3c >> Modules linked in: >> CPU: 1 UID: 0 PID: 365 Comm: bash Tainted: G W 6.13.0-rc1-00018-gacdb4bbda7ab #42 >> Tainted: [W]=WARN >> Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 >> pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) >> pc : try_to_unmap_one+0x8fc/0xd3c >> lr : try_to_unmap_one+0x3dc/0xd3c >> Call trace: >> try_to_unmap_one+0x8fc/0xd3c (P) >> try_to_unmap_one+0x3dc/0xd3c (L) >> rmap_walk_anon+0xdc/0x1f8 >> rmap_walk+0x3c/0x58 >> try_to_unmap+0x88/0x90 >> unmap_poisoned_folio+0x30/0xa8 >> do_migrate_range+0x4a0/0x568 >> offline_pages+0x5a4/0x670 >> memory_block_action+0x17c/0x374 >> memory_subsys_offline+0x3c/0x78 >> device_offline+0xa4/0xd0 >> state_store+0x8c/0xf0 >> dev_attr_store+0x18/0x2c >> sysfs_kf_write+0x44/0x54 >> kernfs_fop_write_iter+0x118/0x1a8 >> vfs_write+0x3a8/0x4bc >> ksys_write+0x6c/0xf8 >> __arm64_sys_write+0x1c/0x28 >> invoke_syscall+0x44/0x100 >> el0_svc_common.constprop.0+0x40/0xe0 >> do_el0_svc+0x1c/0x28 >> el0_svc+0x30/0xd0 >> el0t_64_sync_handler+0xc8/0xcc >> el0t_64_sync+0x198/0x19c >> ---[ end trace 0000000000000000 ]--- >> >> Fixes: 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON") >> Suggested-by: David Hildenbrand <david@redhat.com> >> Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> >> Acked-by: David Hildenbrand <david@redhat.com> > > Thanks. LGTM. One nit below. > > Acked-by: Miaohe Lin <linmiaohe@huawei.com> > >> --- >> mm/internal.h | 5 ++-- >> mm/memory-failure.c | 61 +++++++++++++++++++++++---------------------- >> mm/memory_hotplug.c | 3 ++- >> 3 files changed, 36 insertions(+), 33 deletions(-) >> >> diff --git a/mm/internal.h b/mm/internal.h >> index 9826f7dce607..c9186ca8d7c2 100644 >> --- a/mm/internal.h >> +++ b/mm/internal.h >> @@ -1102,7 +1102,7 @@ static inline int find_next_best_node(int node, nodemask_t *used_node_mask) >> * mm/memory-failure.c >> */ >> #ifdef CONFIG_MEMORY_FAILURE >> -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu); >> +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill); >> void shake_folio(struct folio *folio); >> extern int hwpoison_filter(struct page *p); >> >> @@ -1125,8 +1125,9 @@ unsigned long page_mapped_in_vma(const struct page *page, >> struct vm_area_struct *vma); >> >> #else >> -static inline void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) >> +static inline int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) >> { >> + return -EBUSY; >> } >> #endif >> >> diff --git a/mm/memory-failure.c b/mm/memory-failure.c >> index a7b8ccd29b6f..b5212b6e330a 100644 >> --- a/mm/memory-failure.c >> +++ b/mm/memory-failure.c >> @@ -1556,8 +1556,34 @@ static int get_hwpoison_page(struct page *p, unsigned long flags) >> return ret; >> } >> >> -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) >> +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) >> { >> + enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC | TTU_HWPOISON; >> + struct address_space *mapping; >> + >> + if (folio_test_swapcache(folio)) { >> + pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); >> + ttu &= ~TTU_HWPOISON; >> + } >> + >> + /* >> + * Propagate the dirty bit from PTEs to struct page first, because we >> + * need this to decide if we should kill or just drop the page. >> + * XXX: the dirty test could be racy: set_page_dirty() may not always >> + * be called inside page lock (it's recommended but not enforced). >> + */ >> + mapping = folio_mapping(folio); >> + if (!must_kill && !folio_test_dirty(folio) && mapping && >> + mapping_can_writeback(mapping)) { >> + if (folio_mkclean(folio)) { >> + folio_set_dirty(folio); >> + } else { >> + ttu &= ~TTU_HWPOISON; >> + pr_info("%#lx: corrupted page was clean: dropped without side effects\n", >> + pfn); >> + } >> + } >> + >> if (folio_test_hugetlb(folio) && !folio_test_anon(folio)) { >> struct address_space *mapping; > > This mapping can be removed as we have already defined one above. But this is trivial. Thanks. I will resend this patch with the duplicate defination removed. > > Thanks. > . ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio 2025-02-19 2:50 ` Miaohe Lin 2025-02-19 3:34 ` mawupeng @ 2025-02-19 6:06 ` Wupeng Ma 2025-02-19 23:41 ` Andrew Morton 1 sibling, 1 reply; 13+ messages in thread From: Wupeng Ma @ 2025-02-19 6:06 UTC (permalink / raw) To: akpm, david, osalvador, nao.horiguchi, linmiaohe, mhocko Cc: mawupeng1, linux-mm, linux-kernel From: Ma Wupeng <mawupeng1@huawei.com> Commit 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON") introduce TTU_HWPOISON to replace TTU_IGNORE_HWPOISON in order to stop send SIGBUS signal when accessing an error page after a memory error on a clean folio. However during page migration, anon folio must be set with TTU_HWPOISON during unmap_*(). For pagecache we need some policy just like the one in hwpoison_user_mappings to set this flag. So move this policy from hwpoison_user_mappings to unmap_poisoned_folio to handle this warning properly. Warning will be produced during unamp poison folio with the following log: ------------[ cut here ]------------ WARNING: CPU: 1 PID: 365 at mm/rmap.c:1847 try_to_unmap_one+0x8fc/0xd3c Modules linked in: CPU: 1 UID: 0 PID: 365 Comm: bash Tainted: G W 6.13.0-rc1-00018-gacdb4bbda7ab #42 Tainted: [W]=WARN Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 20400005 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : try_to_unmap_one+0x8fc/0xd3c lr : try_to_unmap_one+0x3dc/0xd3c Call trace: try_to_unmap_one+0x8fc/0xd3c (P) try_to_unmap_one+0x3dc/0xd3c (L) rmap_walk_anon+0xdc/0x1f8 rmap_walk+0x3c/0x58 try_to_unmap+0x88/0x90 unmap_poisoned_folio+0x30/0xa8 do_migrate_range+0x4a0/0x568 offline_pages+0x5a4/0x670 memory_block_action+0x17c/0x374 memory_subsys_offline+0x3c/0x78 device_offline+0xa4/0xd0 state_store+0x8c/0xf0 dev_attr_store+0x18/0x2c sysfs_kf_write+0x44/0x54 kernfs_fop_write_iter+0x118/0x1a8 vfs_write+0x3a8/0x4bc ksys_write+0x6c/0xf8 __arm64_sys_write+0x1c/0x28 invoke_syscall+0x44/0x100 el0_svc_common.constprop.0+0x40/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x30/0xd0 el0t_64_sync_handler+0xc8/0xcc el0t_64_sync+0x198/0x19c ---[ end trace 0000000000000000 ]--- Fixes: 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON") Suggested-by: David Hildenbrand <david@redhat.com> Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> Acked-by: David Hildenbrand <david@redhat.com> Acked-by: Miaohe Lin <linmiaohe@huawei.com> --- mm/internal.h | 5 ++-- mm/memory-failure.c | 63 ++++++++++++++++++++++----------------------- mm/memory_hotplug.c | 3 ++- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/mm/internal.h b/mm/internal.h index 109ef30fee11..20b3535935a3 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -1115,7 +1115,7 @@ static inline int find_next_best_node(int node, nodemask_t *used_node_mask) * mm/memory-failure.c */ #ifdef CONFIG_MEMORY_FAILURE -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu); +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill); void shake_folio(struct folio *folio); extern int hwpoison_filter(struct page *p); @@ -1138,8 +1138,9 @@ unsigned long page_mapped_in_vma(const struct page *page, struct vm_area_struct *vma); #else -static inline void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) +static inline int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) { + return -EBUSY; } #endif diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 995a15eb67e2..327e02fdc029 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1556,11 +1556,35 @@ static int get_hwpoison_page(struct page *p, unsigned long flags) return ret; } -void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) +int unmap_poisoned_folio(struct folio *folio, unsigned long pfn, bool must_kill) { - if (folio_test_hugetlb(folio) && !folio_test_anon(folio)) { - struct address_space *mapping; + enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC | TTU_HWPOISON; + struct address_space *mapping; + + if (folio_test_swapcache(folio)) { + pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); + ttu &= ~TTU_HWPOISON; + } + /* + * Propagate the dirty bit from PTEs to struct page first, because we + * need this to decide if we should kill or just drop the page. + * XXX: the dirty test could be racy: set_page_dirty() may not always + * be called inside page lock (it's recommended but not enforced). + */ + mapping = folio_mapping(folio); + if (!must_kill && !folio_test_dirty(folio) && mapping && + mapping_can_writeback(mapping)) { + if (folio_mkclean(folio)) { + folio_set_dirty(folio); + } else { + ttu &= ~TTU_HWPOISON; + pr_info("%#lx: corrupted page was clean: dropped without side effects\n", + pfn); + } + } + + if (folio_test_hugetlb(folio) && !folio_test_anon(folio)) { /* * For hugetlb folios in shared mappings, try_to_unmap * could potentially call huge_pmd_unshare. Because of @@ -1572,7 +1596,7 @@ void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) if (!mapping) { pr_info("%#lx: could not lock mapping for mapped hugetlb folio\n", folio_pfn(folio)); - return; + return -EBUSY; } try_to_unmap(folio, ttu|TTU_RMAP_LOCKED); @@ -1580,6 +1604,8 @@ void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) } else { try_to_unmap(folio, ttu); } + + return folio_mapped(folio) ? -EBUSY : 0; } /* @@ -1589,8 +1615,6 @@ void unmap_poisoned_folio(struct folio *folio, enum ttu_flags ttu) static bool hwpoison_user_mappings(struct folio *folio, struct page *p, unsigned long pfn, int flags) { - enum ttu_flags ttu = TTU_IGNORE_MLOCK | TTU_SYNC | TTU_HWPOISON; - struct address_space *mapping; LIST_HEAD(tokill); bool unmap_success; int forcekill; @@ -1613,29 +1637,6 @@ static bool hwpoison_user_mappings(struct folio *folio, struct page *p, if (!folio_mapped(folio)) return true; - if (folio_test_swapcache(folio)) { - pr_err("%#lx: keeping poisoned page in swap cache\n", pfn); - ttu &= ~TTU_HWPOISON; - } - - /* - * Propagate the dirty bit from PTEs to struct page first, because we - * need this to decide if we should kill or just drop the page. - * XXX: the dirty test could be racy: set_page_dirty() may not always - * be called inside page lock (it's recommended but not enforced). - */ - mapping = folio_mapping(folio); - if (!(flags & MF_MUST_KILL) && !folio_test_dirty(folio) && mapping && - mapping_can_writeback(mapping)) { - if (folio_mkclean(folio)) { - folio_set_dirty(folio); - } else { - ttu &= ~TTU_HWPOISON; - pr_info("%#lx: corrupted page was clean: dropped without side effects\n", - pfn); - } - } - /* * First collect all the processes that have the page * mapped in dirty form. This has to be done before try_to_unmap, @@ -1643,9 +1644,7 @@ static bool hwpoison_user_mappings(struct folio *folio, struct page *p, */ collect_procs(folio, p, &tokill, flags & MF_ACTION_REQUIRED); - unmap_poisoned_folio(folio, ttu); - - unmap_success = !folio_mapped(folio); + unmap_success = !unmap_poisoned_folio(folio, pfn, flags & MF_MUST_KILL); if (!unmap_success) pr_err("%#lx: failed to unmap page (folio mapcount=%d)\n", pfn, folio_mapcount(folio)); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index e3655f07dd6e..e7e47838fd49 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1833,7 +1833,8 @@ static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) if (WARN_ON(folio_test_lru(folio))) folio_isolate_lru(folio); if (folio_mapped(folio)) - unmap_poisoned_folio(folio, TTU_IGNORE_MLOCK); + unmap_poisoned_folio(folio, pfn, false); + continue; } -- 2.43.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio 2025-02-19 6:06 ` [PATCH v3] " Wupeng Ma @ 2025-02-19 23:41 ` Andrew Morton 0 siblings, 0 replies; 13+ messages in thread From: Andrew Morton @ 2025-02-19 23:41 UTC (permalink / raw) To: Wupeng Ma Cc: david, osalvador, nao.horiguchi, linmiaohe, mhocko, linux-mm, linux-kernel On Wed, 19 Feb 2025 14:06:52 +0800 Wupeng Ma <mawupeng1@huawei.com> wrote: > > ... > Thanks, I queued the below fix, so people can see what changed from v2: From: Ma Wupeng <mawupeng1@huawei.com> Subject: mm-memory-failure-update-ttu-flag-inside-unmap_poisoned_folio-v3 Date: Wed, 19 Feb 2025 14:06:52 +0800 unmap_poisoned_folio(): remove shadowed local `mapping', per Miaohe Link: https://lkml.kernel.org/r/20250219060653.3849083-1-mawupeng1@huawei.com Fixes: 6da6b1d4a7df ("mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON") Suggested-by: David Hildenbrand <david@redhat.com> Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> Acked-by: David Hildenbrand <david@redhat.com> Acked-by: Miaohe Lin <linmiaohe@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> --- mm/memory-failure.c | 2 -- 1 file changed, 2 deletions(-) --- a/mm/memory-failure.c~mm-memory-failure-update-ttu-flag-inside-unmap_poisoned_folio-v3 +++ a/mm/memory-failure.c @@ -1585,8 +1585,6 @@ int unmap_poisoned_folio(struct folio *f } if (folio_test_hugetlb(folio) && !folio_test_anon(folio)) { - struct address_space *mapping; - /* * For hugetlb folios in shared mappings, try_to_unmap * could potentially call huge_pmd_unshare. Because of _ ^ permalink raw reply [flat|nested] 13+ messages in thread
* mm: memory-failure: update ttu flag inside unmap_poisoned_folio 2025-02-17 1:43 ` [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio Wupeng Ma 2025-02-19 2:50 ` Miaohe Lin @ 2025-03-19 17:21 ` Arthur Marsh 2025-03-20 2:40 ` mawupeng 1 sibling, 1 reply; 13+ messages in thread From: Arthur Marsh @ 2025-03-19 17:21 UTC (permalink / raw) To: mawupeng1 Cc: akpm, david, linmiaohe, linux-kernel, linux-mm, mhocko, nao.horiguchi, osalvador On recent kernel builds on a system with the following CPU with integrated GPU: AMD Ryzen 5 5500GT with Radeon Graphics using the integrated GPU, on the following motherboard: System manufacturer System Product Name/PRIME B350M-A, BIOS 6232 09/29/2024 I've been getting the error below on the initial loading of chromium after booting, which I git-bisected back to commit b81679b1633aa43c0d973adfa816d78c1ed0d032 (which I am replying to now): : [ 281.651311] WARNING: CPU: 4 PID: 3525 at mm/util.c:674 __kvmalloc_node_noprof+0xc8/0xe0 [ 281.651322] Modules linked in: snd_seq_dummy snd_hrtimer snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device fuse bnep bluetooth rfkill cpufreq_userspace cpufreq_conservative cpufreq_powersave binfmt_misc nf_tables scsi_transport_iscsi nfnetlink sch_fq_codel exfat parport_pc ppdev lp parport rtl2832_sdr videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_common videodev fc0012 rtl2832 i2c_mux regmap_i2c dvb_usb_rtl28xxu amdgpu dvb_usb_v2 dvb_core mc amdxcp gpu_sched snd_hda_codec_realtek snd_hda_codec_hdmi drm_panel_backlight_quirks cec snd_hda_codec_generic drm_buddy drm_ttm_helper ttm snd_hda_scodec_component snd_hda_intel drm_client_lib drm_exec drm_suballoc_helper snd_intel_dspcfg drm_display_helper snd_hda_codec intel_rapl_msr intel_rapl_common snd_hda_core drm_kms_helper tpm_crb tpm_tis tpm_tis_core snd_hwdep drm snd_pcm tpm edac_mce_amd sha512_ssse3 sha3_generic jitterentropy_rng hmac drbg libaescfb snd_timer ansi_cprng sha512_generic i2c_algo_bit ecdh_generic snd sha256_ssse3 sha1_ssse3 [ 281.651387] ccp aesni_intel ecc video mfd_core gf128mul crypto_simd cryptd button evdev soundcore wmi pcspkr rng_core k10temp ext4 crc16 mbcache jbd2 hid_generic usbhid sg uas sr_mod hid usb_storage cdrom sd_mod sp5100_tco ahci libahci xhci_pci r8169 xhci_hcd libata realtek mdio_devres serio_raw i2c_piix4 usbcore scsi_mod i2c_smbus libphy scsi_common usb_common [ 281.651424] CPU: 4 UID: 1000 PID: 3525 Comm: chromium Tainted: G W 6.14.0-rc3+ #6448 [ 281.651429] Tainted: [W]=WARN [ 281.651430] Hardware name: System manufacturer System Product Name/PRIME B350M-A, BIOS 6232 09/29/2024 [ 281.651433] RIP: 0010:__kvmalloc_node_noprof+0xc8/0xe0 [ 281.651436] Code: 64 24 08 41 89 d8 be 01 00 00 00 48 89 ef 48 01 d1 48 89 44 24 10 48 c7 04 24 00 04 00 00 e8 6f 25 04 00 eb 87 80 e7 20 75 82 <0f> 0b 90 0f 1f 44 00 00 e9 75 ff ff ff 66 66 2e 0f 1f 84 00 00 00 [ 281.651438] RSP: 0018:ffffb1334837fc40 EFLAGS: 00010246 [ 281.651440] RAX: 0000000000000000 RBX: 00000000000000c0 RCX: 0000000000000016 [ 281.651442] RDX: 0000000000000016 RSI: ffffffffbe164ba8 RDI: 0000000000052cc0 [ 281.651443] RBP: 0000000498843b00 R08: ffffb1334837fda8 R09: ffffb1334837fdb8 [ 281.651444] R10: 0000000000000018 R11: 0000000000000000 R12: 00000000ffffffff [ 281.651445] R13: ffffb1334837fcb8 R14: 0000000000000000 R15: ffff997e75680010 [ 281.651446] FS: 00007fda628ef500(0000) GS:ffff99854e700000(0000) knlGS:0000000000000000 [ 281.651447] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 281.651448] CR2: 00007fda6554b302 CR3: 000000013df40000 CR4: 0000000000750ef0 [ 281.651449] PKRU: 55555558 [ 281.651450] Call Trace: [ 281.651451] <TASK> [ 281.651453] ? __kvmalloc_node_noprof+0xc8/0xe0 [ 281.651455] ? __warn.cold+0xad/0x109 [ 281.651459] ? __kvmalloc_node_noprof+0xc8/0xe0 [ 281.651461] ? report_bug+0x102/0x190 [ 281.651470] ? handle_bug+0x59/0xa0 [ 281.651474] ? exc_invalid_op+0x1f/0x90 [ 281.651477] ? asm_exc_invalid_op+0x16/0x20 [ 281.651481] ? __kmalloc_node_noprof+0x278/0x360 [ 281.651487] ? __kvmalloc_node_noprof+0xc8/0xe0 [ 281.651489] ? srso_alias_return_thunk+0x5/0xfbef5 [ 281.651491] ? chrdev_open+0xad/0x220 [ 281.651496] amdgpu_bo_create_list_entry_array+0x47/0x120 [amdgpu] [ 281.651729] amdgpu_bo_list_ioctl+0x4e/0x330 [amdgpu] [ 281.651823] ? __pfx_amdgpu_bo_list_ioctl+0x10/0x10 [amdgpu] [ 281.651914] drm_ioctl_kernel+0xa6/0x100 [drm] [ 281.651942] drm_ioctl+0x236/0x540 [drm] [ 281.651954] ? __pfx_amdgpu_bo_list_ioctl+0x10/0x10 [amdgpu] [ 281.652047] ? srso_alias_return_thunk+0x5/0xfbef5 [ 281.652049] ? preempt_count_add+0x51/0xd0 [ 281.652053] ? srso_alias_return_thunk+0x5/0xfbef5 [ 281.652054] ? migrate_enable+0xc0/0xf0 [ 281.652058] amdgpu_drm_ioctl+0x58/0xa0 [amdgpu] [ 281.652138] __x64_sys_ioctl+0x55f/0xab0 [ 281.652143] ? srso_alias_return_thunk+0x5/0xfbef5 [ 281.652145] ? do_sys_openat2+0x74/0xb0 [ 281.652148] ? do_user_addr_fault+0x3a0/0x660 [ 281.652153] do_syscall_64+0x47/0x110 [ 281.652155] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 281.652157] RIP: 0033:0x7fda65ad08db [ 281.652159] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1c 48 8b 44 24 18 64 48 2b 04 25 28 00 00 [ 281.652160] RSP: 002b:00007ffc93108640 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 [ 281.652162] RAX: ffffffffffffffda RBX: 00003cfc000ac640 RCX: 00007fda65ad08db [ 281.652162] RDX: 00007ffc931086f0 RSI: 00000000c0106443 RDI: 0000000000000014 [ 281.652163] RBP: 00007ffc931086f0 R08: 0000000000000000 R09: 0000000000000000 [ 281.652164] R10: 000000000000006c R11: 0000000000000246 R12: 00000000c0106443 [ 281.652165] R13: 0000000000000014 R14: 00007ffc93108760 R15: 00003cfc000ac658 [ 281.652168] </TASK> [ 281.652168] ---[ end trace 0000000000000000 ]--- chromium still loads and runs fine, but I am left wondering why this message is appearing. I can supply full dmesg and .config if required. Arthur. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: mm: memory-failure: update ttu flag inside unmap_poisoned_folio 2025-03-19 17:21 ` Arthur Marsh @ 2025-03-20 2:40 ` mawupeng 0 siblings, 0 replies; 13+ messages in thread From: mawupeng @ 2025-03-20 2:40 UTC (permalink / raw) To: arthur.marsh Cc: mawupeng1, akpm, david, linmiaohe, linux-kernel, linux-mm, mhocko, nao.horiguchi, osalvador On 2025/3/20 1:21, Arthur Marsh wrote: > On recent kernel builds on a system with the following CPU with integrated GPU: > > AMD Ryzen 5 5500GT with Radeon Graphics > > using the integrated GPU, on the following motherboard: > > System manufacturer System Product Name/PRIME B350M-A, BIOS 6232 09/29/2024 > > I've been getting the error below on the initial loading of chromium after > booting, which I git-bisected back to commit > > b81679b1633aa43c0d973adfa816d78c1ed0d032 (which I am replying to now): > > : > > [ 281.651311] WARNING: CPU: 4 PID: 3525 at mm/util.c:674 __kvmalloc_node_noprof+0xc8/0xe0 > [ 281.651322] Modules linked in: snd_seq_dummy snd_hrtimer snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device fuse bnep bluetooth rfkill cpufreq_userspace cpufreq_conservative cpufreq_powersave binfmt_misc nf_tables scsi_transport_iscsi nfnetlink sch_fq_codel exfat parport_pc ppdev lp parport rtl2832_sdr videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_common videodev fc0012 rtl2832 i2c_mux regmap_i2c dvb_usb_rtl28xxu amdgpu dvb_usb_v2 dvb_core mc amdxcp gpu_sched snd_hda_codec_realtek snd_hda_codec_hdmi drm_panel_backlight_quirks cec snd_hda_codec_generic drm_buddy drm_ttm_helper ttm snd_hda_scodec_component snd_hda_intel drm_client_lib drm_exec drm_suballoc_helper snd_intel_dspcfg drm_display_helper snd_hda_codec intel_rapl_msr intel_rapl_common snd_hda_core drm_kms_helper tpm_crb tpm_tis tpm_tis_core snd_hwdep drm snd_pcm tpm edac_mce_amd sha512_ssse3 sha3_generic jitterentropy_rng hmac drbg libaescfb snd_timer ansi_cprng sha512_generic i2c_algo_bit ecdh_generic snd sha256_ssse3 sha1_ssse3 > [ 281.651387] ccp aesni_intel ecc video mfd_core gf128mul crypto_simd cryptd button evdev soundcore wmi pcspkr rng_core k10temp ext4 crc16 mbcache jbd2 hid_generic usbhid sg uas sr_mod hid usb_storage cdrom sd_mod sp5100_tco ahci libahci xhci_pci r8169 xhci_hcd libata realtek mdio_devres serio_raw i2c_piix4 usbcore scsi_mod i2c_smbus libphy scsi_common usb_common > [ 281.651424] CPU: 4 UID: 1000 PID: 3525 Comm: chromium Tainted: G W 6.14.0-rc3+ #6448 > [ 281.651429] Tainted: [W]=WARN > [ 281.651430] Hardware name: System manufacturer System Product Name/PRIME B350M-A, BIOS 6232 09/29/2024 > [ 281.651433] RIP: 0010:__kvmalloc_node_noprof+0xc8/0xe0 > [ 281.651436] Code: 64 24 08 41 89 d8 be 01 00 00 00 48 89 ef 48 01 d1 48 89 44 24 10 48 c7 04 24 00 04 00 00 e8 6f 25 04 00 eb 87 80 e7 20 75 82 <0f> 0b 90 0f 1f 44 00 00 e9 75 ff ff ff 66 66 2e 0f 1f 84 00 00 00 > [ 281.651438] RSP: 0018:ffffb1334837fc40 EFLAGS: 00010246 > [ 281.651440] RAX: 0000000000000000 RBX: 00000000000000c0 RCX: 0000000000000016 > [ 281.651442] RDX: 0000000000000016 RSI: ffffffffbe164ba8 RDI: 0000000000052cc0 > [ 281.651443] RBP: 0000000498843b00 R08: ffffb1334837fda8 R09: ffffb1334837fdb8 > [ 281.651444] R10: 0000000000000018 R11: 0000000000000000 R12: 00000000ffffffff > [ 281.651445] R13: ffffb1334837fcb8 R14: 0000000000000000 R15: ffff997e75680010 > [ 281.651446] FS: 00007fda628ef500(0000) GS:ffff99854e700000(0000) knlGS:0000000000000000 > [ 281.651447] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 281.651448] CR2: 00007fda6554b302 CR3: 000000013df40000 CR4: 0000000000750ef0 > [ 281.651449] PKRU: 55555558 > [ 281.651450] Call Trace: > [ 281.651451] <TASK> > [ 281.651453] ? __kvmalloc_node_noprof+0xc8/0xe0 > [ 281.651455] ? __warn.cold+0xad/0x109 > [ 281.651459] ? __kvmalloc_node_noprof+0xc8/0xe0 > [ 281.651461] ? report_bug+0x102/0x190 > [ 281.651470] ? handle_bug+0x59/0xa0 > [ 281.651474] ? exc_invalid_op+0x1f/0x90 > [ 281.651477] ? asm_exc_invalid_op+0x16/0x20 > [ 281.651481] ? __kmalloc_node_noprof+0x278/0x360 > [ 281.651487] ? __kvmalloc_node_noprof+0xc8/0xe0 > [ 281.651489] ? srso_alias_return_thunk+0x5/0xfbef5 > [ 281.651491] ? chrdev_open+0xad/0x220 > [ 281.651496] amdgpu_bo_create_list_entry_array+0x47/0x120 [amdgpu] > [ 281.651729] amdgpu_bo_list_ioctl+0x4e/0x330 [amdgpu] > [ 281.651823] ? __pfx_amdgpu_bo_list_ioctl+0x10/0x10 [amdgpu] > [ 281.651914] drm_ioctl_kernel+0xa6/0x100 [drm] > [ 281.651942] drm_ioctl+0x236/0x540 [drm] > [ 281.651954] ? __pfx_amdgpu_bo_list_ioctl+0x10/0x10 [amdgpu] > [ 281.652047] ? srso_alias_return_thunk+0x5/0xfbef5 > [ 281.652049] ? preempt_count_add+0x51/0xd0 > [ 281.652053] ? srso_alias_return_thunk+0x5/0xfbef5 > [ 281.652054] ? migrate_enable+0xc0/0xf0 > [ 281.652058] amdgpu_drm_ioctl+0x58/0xa0 [amdgpu] > [ 281.652138] __x64_sys_ioctl+0x55f/0xab0 > [ 281.652143] ? srso_alias_return_thunk+0x5/0xfbef5 > [ 281.652145] ? do_sys_openat2+0x74/0xb0 > [ 281.652148] ? do_user_addr_fault+0x3a0/0x660 > [ 281.652153] do_syscall_64+0x47/0x110 > [ 281.652155] entry_SYSCALL_64_after_hwframe+0x76/0x7e > [ 281.652157] RIP: 0033:0x7fda65ad08db > [ 281.652159] Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1c 48 8b 44 24 18 64 48 2b 04 25 28 00 00 > [ 281.652160] RSP: 002b:00007ffc93108640 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 > [ 281.652162] RAX: ffffffffffffffda RBX: 00003cfc000ac640 RCX: 00007fda65ad08db > [ 281.652162] RDX: 00007ffc931086f0 RSI: 00000000c0106443 RDI: 0000000000000014 > [ 281.652163] RBP: 00007ffc931086f0 R08: 0000000000000000 R09: 0000000000000000 > [ 281.652164] R10: 000000000000006c R11: 0000000000000246 R12: 00000000c0106443 > [ 281.652165] R13: 0000000000000014 R14: 00007ffc93108760 R15: 00003cfc000ac658 > [ 281.652168] </TASK> > [ 281.652168] ---[ end trace 0000000000000000 ]--- It seems there is no connection with this patch. > > chromium still loads and runs fine, but I am left wondering why this message > is appearing. > > I can supply full dmesg and .config if required. > > Arthur. > > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range 2025-02-17 1:43 [PATCH v3 0/3] mm: memory_failure: unmap poisoned filio during migrate properly Wupeng Ma 2025-02-17 1:43 ` [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio Wupeng Ma @ 2025-02-17 1:43 ` Wupeng Ma 2025-02-17 9:30 ` David Hildenbrand 2025-02-19 3:15 ` Miaohe Lin 2025-02-17 1:43 ` [PATCH v3 3/3] hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio Wupeng Ma 2 siblings, 2 replies; 13+ messages in thread From: Wupeng Ma @ 2025-02-17 1:43 UTC (permalink / raw) To: akpm, david, osalvador, nao.horiguchi, linmiaohe, mhocko Cc: mawupeng1, linux-mm, linux-kernel From: Ma Wupeng <mawupeng1@huawei.com> If a folio has an increased reference count, folio_try_get() will acquire it, perform necessary operations, and then release it. In the case of a poisoned folio without an elevated reference count (which is unlikely for memory-failure), folio_try_get() will simply bypass it. Therefore, relocate the folio_try_get() function, responsible for checking and acquiring this reference count at first. Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> --- mm/memory_hotplug.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 3de661e57e92..3669b3e2d962 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1795,12 +1795,12 @@ static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) if (folio_test_large(folio)) pfn = folio_pfn(folio) + folio_nr_pages(folio) - 1; - /* - * HWPoison pages have elevated reference counts so the migration would - * fail on them. It also doesn't make any sense to migrate them in the - * first place. Still try to unmap such a page in case it is still mapped - * (keep the unmap as the catch all safety net). - */ + if (!folio_try_get(folio)) + continue; + + if (unlikely(page_folio(page) != folio)) + goto put_folio; + if (folio_test_hwpoison(folio) || (folio_test_large(folio) && folio_test_has_hwpoisoned(folio))) { if (WARN_ON(folio_test_lru(folio))) @@ -1808,14 +1808,8 @@ static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) if (folio_mapped(folio)) unmap_poisoned_folio(folio, pfn, false); - continue; - } - - if (!folio_try_get(folio)) - continue; - - if (unlikely(page_folio(page) != folio)) goto put_folio; + } if (!isolate_folio_to_list(folio, &source)) { if (__ratelimit(&migrate_rs)) { -- 2.43.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range 2025-02-17 1:43 ` [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range Wupeng Ma @ 2025-02-17 9:30 ` David Hildenbrand 2025-02-19 3:15 ` Miaohe Lin 1 sibling, 0 replies; 13+ messages in thread From: David Hildenbrand @ 2025-02-17 9:30 UTC (permalink / raw) To: Wupeng Ma, akpm, osalvador, nao.horiguchi, linmiaohe, mhocko Cc: linux-mm, linux-kernel On 17.02.25 02:43, Wupeng Ma wrote: > From: Ma Wupeng <mawupeng1@huawei.com> > > If a folio has an increased reference count, folio_try_get() will acquire > it, perform necessary operations, and then release it. In the case of a > poisoned folio without an elevated reference count (which is unlikely for > memory-failure), folio_try_get() will simply bypass it. > > Therefore, relocate the folio_try_get() function, responsible for checking > and acquiring this reference count at first. > > Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> > --- Acked-by: David Hildenbrand <david@redhat.com> -- Cheers, David / dhildenb ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range 2025-02-17 1:43 ` [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range Wupeng Ma 2025-02-17 9:30 ` David Hildenbrand @ 2025-02-19 3:15 ` Miaohe Lin 1 sibling, 0 replies; 13+ messages in thread From: Miaohe Lin @ 2025-02-19 3:15 UTC (permalink / raw) To: Wupeng Ma Cc: linux-mm, linux-kernel, akpm, david, osalvador, nao.horiguchi, mhocko On 2025/2/17 9:43, Wupeng Ma wrote: > From: Ma Wupeng <mawupeng1@huawei.com> > > If a folio has an increased reference count, folio_try_get() will acquire > it, perform necessary operations, and then release it. In the case of a > poisoned folio without an elevated reference count (which is unlikely for > memory-failure), folio_try_get() will simply bypass it. > > Therefore, relocate the folio_try_get() function, responsible for checking > and acquiring this reference count at first. > > Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> Acked-by: Miaohe Lin <linmiaohe@huawei.com> Thanks. . ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v3 3/3] hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio 2025-02-17 1:43 [PATCH v3 0/3] mm: memory_failure: unmap poisoned filio during migrate properly Wupeng Ma 2025-02-17 1:43 ` [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio Wupeng Ma 2025-02-17 1:43 ` [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range Wupeng Ma @ 2025-02-17 1:43 ` Wupeng Ma 2025-02-19 3:17 ` Miaohe Lin 2 siblings, 1 reply; 13+ messages in thread From: Wupeng Ma @ 2025-02-17 1:43 UTC (permalink / raw) To: akpm, david, osalvador, nao.horiguchi, linmiaohe, mhocko Cc: mawupeng1, linux-mm, linux-kernel From: Ma Wupeng <mawupeng1@huawei.com> Commit b15c87263a69 ("hwpoison, memory_hotplug: allow hwpoisoned pages to be offlined) add page poison checks in do_migrate_range in order to make offline hwpoisoned page possible by introducing isolate_lru_page and try_to_unmap for hwpoisoned page. However folio lock must be held before calling try_to_unmap. Add it to fix this problem. Warning will be produced if folio is not locked during unmap: ------------[ cut here ]------------ kernel BUG at ./include/linux/swapops.h:400! Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP Modules linked in: CPU: 4 UID: 0 PID: 411 Comm: bash Tainted: G W 6.13.0-rc1-00016-g3c434c7ee82a-dirty #41 Tainted: [W]=WARN Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : try_to_unmap_one+0xb08/0xd3c lr : try_to_unmap_one+0x3dc/0xd3c Call trace: try_to_unmap_one+0xb08/0xd3c (P) try_to_unmap_one+0x3dc/0xd3c (L) rmap_walk_anon+0xdc/0x1f8 rmap_walk+0x3c/0x58 try_to_unmap+0x88/0x90 unmap_poisoned_folio+0x30/0xa8 do_migrate_range+0x4a0/0x568 offline_pages+0x5a4/0x670 memory_block_action+0x17c/0x374 memory_subsys_offline+0x3c/0x78 device_offline+0xa4/0xd0 state_store+0x8c/0xf0 dev_attr_store+0x18/0x2c sysfs_kf_write+0x44/0x54 kernfs_fop_write_iter+0x118/0x1a8 vfs_write+0x3a8/0x4bc ksys_write+0x6c/0xf8 __arm64_sys_write+0x1c/0x28 invoke_syscall+0x44/0x100 el0_svc_common.constprop.0+0x40/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x30/0xd0 el0t_64_sync_handler+0xc8/0xcc el0t_64_sync+0x198/0x19c Code: f9407be0 b5fff320 d4210000 17ffff97 (d4210000) ---[ end trace 0000000000000000 ]--- Fixes: b15c87263a69 ("hwpoison, memory_hotplug: allow hwpoisoned pages to be offlined") Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> Acked-by: David Hildenbrand <david@redhat.com> --- mm/memory_hotplug.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 3669b3e2d962..c3de35389269 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1805,8 +1805,11 @@ static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn) (folio_test_large(folio) && folio_test_has_hwpoisoned(folio))) { if (WARN_ON(folio_test_lru(folio))) folio_isolate_lru(folio); - if (folio_mapped(folio)) + if (folio_mapped(folio)) { + folio_lock(folio); unmap_poisoned_folio(folio, pfn, false); + folio_unlock(folio); + } goto put_folio; } -- 2.43.0 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 3/3] hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio 2025-02-17 1:43 ` [PATCH v3 3/3] hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio Wupeng Ma @ 2025-02-19 3:17 ` Miaohe Lin 0 siblings, 0 replies; 13+ messages in thread From: Miaohe Lin @ 2025-02-19 3:17 UTC (permalink / raw) To: Wupeng Ma Cc: linux-mm, linux-kernel, akpm, david, osalvador, nao.horiguchi, mhocko On 2025/2/17 9:43, Wupeng Ma wrote: > From: Ma Wupeng <mawupeng1@huawei.com> > > Commit b15c87263a69 ("hwpoison, memory_hotplug: allow hwpoisoned pages to > be offlined) add page poison checks in do_migrate_range in order to make > offline hwpoisoned page possible by introducing isolate_lru_page and > try_to_unmap for hwpoisoned page. However folio lock must be held before > calling try_to_unmap. Add it to fix this problem. > > Warning will be produced if folio is not locked during unmap: > > ------------[ cut here ]------------ > kernel BUG at ./include/linux/swapops.h:400! > Internal error: Oops - BUG: 00000000f2000800 [#1] PREEMPT SMP > Modules linked in: > CPU: 4 UID: 0 PID: 411 Comm: bash Tainted: G W 6.13.0-rc1-00016-g3c434c7ee82a-dirty #41 > Tainted: [W]=WARN > Hardware name: QEMU QEMU Virtual Machine, BIOS 0.0.0 02/06/2015 > pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) > pc : try_to_unmap_one+0xb08/0xd3c > lr : try_to_unmap_one+0x3dc/0xd3c > Call trace: > try_to_unmap_one+0xb08/0xd3c (P) > try_to_unmap_one+0x3dc/0xd3c (L) > rmap_walk_anon+0xdc/0x1f8 > rmap_walk+0x3c/0x58 > try_to_unmap+0x88/0x90 > unmap_poisoned_folio+0x30/0xa8 > do_migrate_range+0x4a0/0x568 > offline_pages+0x5a4/0x670 > memory_block_action+0x17c/0x374 > memory_subsys_offline+0x3c/0x78 > device_offline+0xa4/0xd0 > state_store+0x8c/0xf0 > dev_attr_store+0x18/0x2c > sysfs_kf_write+0x44/0x54 > kernfs_fop_write_iter+0x118/0x1a8 > vfs_write+0x3a8/0x4bc > ksys_write+0x6c/0xf8 > __arm64_sys_write+0x1c/0x28 > invoke_syscall+0x44/0x100 > el0_svc_common.constprop.0+0x40/0xe0 > do_el0_svc+0x1c/0x28 > el0_svc+0x30/0xd0 > el0t_64_sync_handler+0xc8/0xcc > el0t_64_sync+0x198/0x19c > Code: f9407be0 b5fff320 d4210000 17ffff97 (d4210000) > ---[ end trace 0000000000000000 ]--- > > Fixes: b15c87263a69 ("hwpoison, memory_hotplug: allow hwpoisoned pages to be offlined") > Signed-off-by: Ma Wupeng <mawupeng1@huawei.com> > Acked-by: David Hildenbrand <david@redhat.com> Acked-by: Miaohe Lin <linmiaohe@huawei.com> Thanks. . ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-03-20 2:40 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-02-17 1:43 [PATCH v3 0/3] mm: memory_failure: unmap poisoned filio during migrate properly Wupeng Ma 2025-02-17 1:43 ` [PATCH v3 1/3] mm: memory-failure: update ttu flag inside unmap_poisoned_folio Wupeng Ma 2025-02-19 2:50 ` Miaohe Lin 2025-02-19 3:34 ` mawupeng 2025-02-19 6:06 ` [PATCH v3] " Wupeng Ma 2025-02-19 23:41 ` Andrew Morton 2025-03-19 17:21 ` Arthur Marsh 2025-03-20 2:40 ` mawupeng 2025-02-17 1:43 ` [PATCH v3 2/3] mm: memory-hotplug: check folio ref count first in do_migrate_range Wupeng Ma 2025-02-17 9:30 ` David Hildenbrand 2025-02-19 3:15 ` Miaohe Lin 2025-02-17 1:43 ` [PATCH v3 3/3] hwpoison, memory_hotplug: lock folio before unmap hwpoisoned folio Wupeng Ma 2025-02-19 3:17 ` Miaohe Lin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox