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
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.
.
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.
> .
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
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
_
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.
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. > >
© 2016 - 2025 Red Hat, Inc.