linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [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

* [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

* [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 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 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 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

* 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

* 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

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