linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 6.1.y 0/2] mm/migrate_device: don't add folio to be freed to LRU in migrate_device_finalize()
       [not found] <2025022402-footprint-usher-aa6e@gregkh>
@ 2025-09-25  8:23 ` David Hildenbrand
  2025-09-25  8:23   ` [PATCH 6.1.y 1/2] mm: migrate_device: use more folio " David Hildenbrand
  2025-09-25  8:23   ` [PATCH 6.1.y 2/2] mm/migrate_device: don't add folio to be freed to LRU " David Hildenbrand
  0 siblings, 2 replies; 3+ messages in thread
From: David Hildenbrand @ 2025-09-25  8:23 UTC (permalink / raw)
  To: stable
  Cc: linux-mm, David Hildenbrand, Alistair Popple, Andrew Morton,
	Baolin Wang, Jérôme Glisse, John Hubbard,
	Jonathan Corbet, Kefeng Wang, Matthew Wilcox (Oracle),
	Vishal Moola (Oracle),
	Zi Yan

Just got reminded that I never did these backports.

Patch #1 is a clean cherry pick to make the fix in patch #2 easier to
backport. One minor context conflict.

David Hildenbrand (1):
  mm/migrate_device: don't add folio to be freed to LRU in
    migrate_device_finalize()

Kefeng Wang (1):
  mm: migrate_device: use more folio in migrate_device_finalize()

 mm/migrate_device.c | 42 ++++++++++++++++++++----------------------
 1 file changed, 20 insertions(+), 22 deletions(-)


base-commit: 363a599da6d9d9aaeea97fceff615580e845c72b
-- 
2.51.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 6.1.y 1/2] mm: migrate_device: use more folio in migrate_device_finalize()
  2025-09-25  8:23 ` [PATCH 6.1.y 0/2] mm/migrate_device: don't add folio to be freed to LRU in migrate_device_finalize() David Hildenbrand
@ 2025-09-25  8:23   ` David Hildenbrand
  2025-09-25  8:23   ` [PATCH 6.1.y 2/2] mm/migrate_device: don't add folio to be freed to LRU " David Hildenbrand
  1 sibling, 0 replies; 3+ messages in thread
From: David Hildenbrand @ 2025-09-25  8:23 UTC (permalink / raw)
  To: stable
  Cc: linux-mm, David Hildenbrand, Alistair Popple, Andrew Morton,
	Baolin Wang, Jérôme Glisse, John Hubbard,
	Jonathan Corbet, Kefeng Wang, Matthew Wilcox (Oracle),
	Vishal Moola (Oracle),
	Zi Yan

From: Kefeng Wang <wangkefeng.wang@huawei.com>

Saves a couple of calls to compound_head() and remove last two callers of
putback_lru_page().

Link: https://lkml.kernel.org/r/20240826065814.1336616-5-wangkefeng.wang@huawei.com
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Reviewed-by: Alistair Popple <apopple@nvidia.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
(cherry picked from commit 58bf8c2bf47550bc94fea9cafd2bc7304d97102c)
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 mm/migrate_device.c | 41 ++++++++++++++++++++++-------------------
 1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 721b2365dbca9..180dbb99c320b 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -829,42 +829,45 @@ void migrate_device_finalize(unsigned long *src_pfns,
 	unsigned long i;
 
 	for (i = 0; i < npages; i++) {
-		struct folio *dst, *src;
+		struct folio *dst = NULL, *src = NULL;
 		struct page *newpage = migrate_pfn_to_page(dst_pfns[i]);
 		struct page *page = migrate_pfn_to_page(src_pfns[i]);
 
+		if (newpage)
+			dst = page_folio(newpage);
+
 		if (!page) {
-			if (newpage) {
-				unlock_page(newpage);
-				put_page(newpage);
+			if (dst) {
+				folio_unlock(dst);
+				folio_put(dst);
 			}
 			continue;
 		}
 
-		if (!(src_pfns[i] & MIGRATE_PFN_MIGRATE) || !newpage) {
-			if (newpage) {
-				unlock_page(newpage);
-				put_page(newpage);
+		src = page_folio(page);
+
+		if (!(src_pfns[i] & MIGRATE_PFN_MIGRATE) || !dst) {
+			if (dst) {
+				folio_unlock(dst);
+				folio_put(dst);
 			}
-			newpage = page;
+			dst = src;
 		}
 
-		src = page_folio(page);
-		dst = page_folio(newpage);
 		remove_migration_ptes(src, dst, false);
 		folio_unlock(src);
 
-		if (is_zone_device_page(page))
-			put_page(page);
+		if (folio_is_zone_device(src))
+			folio_put(src);
 		else
-			putback_lru_page(page);
+			folio_putback_lru(src);
 
-		if (newpage != page) {
-			unlock_page(newpage);
-			if (is_zone_device_page(newpage))
-				put_page(newpage);
+		if (dst != src) {
+			folio_unlock(dst);
+			if (folio_is_zone_device(dst))
+				folio_put(dst);
 			else
-				putback_lru_page(newpage);
+				folio_putback_lru(dst);
 		}
 	}
 }
-- 
2.51.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 6.1.y 2/2] mm/migrate_device: don't add folio to be freed to LRU in migrate_device_finalize()
  2025-09-25  8:23 ` [PATCH 6.1.y 0/2] mm/migrate_device: don't add folio to be freed to LRU in migrate_device_finalize() David Hildenbrand
  2025-09-25  8:23   ` [PATCH 6.1.y 1/2] mm: migrate_device: use more folio " David Hildenbrand
@ 2025-09-25  8:23   ` David Hildenbrand
  1 sibling, 0 replies; 3+ messages in thread
From: David Hildenbrand @ 2025-09-25  8:23 UTC (permalink / raw)
  To: stable
  Cc: linux-mm, David Hildenbrand, Alistair Popple, Andrew Morton,
	Baolin Wang, Jérôme Glisse, John Hubbard,
	Jonathan Corbet, Kefeng Wang, Matthew Wilcox (Oracle),
	Vishal Moola (Oracle),
	Zi Yan

If migration succeeded, we called
folio_migrate_flags()->mem_cgroup_migrate() to migrate the memcg from the
old to the new folio.  This will set memcg_data of the old folio to 0.

Similarly, if migration failed, memcg_data of the dst folio is left unset.

If we call folio_putback_lru() on such folios (memcg_data == 0), we will
add the folio to be freed to the LRU, making memcg code unhappy.  Running
the hmm selftests:

  # ./hmm-tests
  ...
  #  RUN           hmm.hmm_device_private.migrate ...
  [  102.078007][T14893] page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x7ff27d200 pfn:0x13cc00
  [  102.079974][T14893] anon flags: 0x17ff00000020018(uptodate|dirty|swapbacked|node=0|zone=2|lastcpupid=0x7ff)
  [  102.082037][T14893] raw: 017ff00000020018 dead000000000100 dead000000000122 ffff8881353896c9
  [  102.083687][T14893] raw: 00000007ff27d200 0000000000000000 00000001ffffffff 0000000000000000
  [  102.085331][T14893] page dumped because: VM_WARN_ON_ONCE_FOLIO(!memcg && !mem_cgroup_disabled())
  [  102.087230][T14893] ------------[ cut here ]------------
  [  102.088279][T14893] WARNING: CPU: 0 PID: 14893 at ./include/linux/memcontrol.h:726 folio_lruvec_lock_irqsave+0x10e/0x170
  [  102.090478][T14893] Modules linked in:
  [  102.091244][T14893] CPU: 0 UID: 0 PID: 14893 Comm: hmm-tests Not tainted 6.13.0-09623-g6c216bc522fd #151
  [  102.093089][T14893] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-2.fc40 04/01/2014
  [  102.094848][T14893] RIP: 0010:folio_lruvec_lock_irqsave+0x10e/0x170
  [  102.096104][T14893] Code: ...
  [  102.099908][T14893] RSP: 0018:ffffc900236c37b0 EFLAGS: 00010293
  [  102.101152][T14893] RAX: 0000000000000000 RBX: ffffea0004f30000 RCX: ffffffff8183f426
  [  102.102684][T14893] RDX: ffff8881063cb880 RSI: ffffffff81b8117f RDI: ffff8881063cb880
  [  102.104227][T14893] RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000
  [  102.105757][T14893] R10: 0000000000000001 R11: 0000000000000002 R12: ffffc900236c37d8
  [  102.107296][T14893] R13: ffff888277a2bcb0 R14: 000000000000001f R15: 0000000000000000
  [  102.108830][T14893] FS:  00007ff27dbdd740(0000) GS:ffff888277a00000(0000) knlGS:0000000000000000
  [  102.110643][T14893] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  [  102.111924][T14893] CR2: 00007ff27d400000 CR3: 000000010866e000 CR4: 0000000000750ef0
  [  102.113478][T14893] PKRU: 55555554
  [  102.114172][T14893] Call Trace:
  [  102.114805][T14893]  <TASK>
  [  102.115397][T14893]  ? folio_lruvec_lock_irqsave+0x10e/0x170
  [  102.116547][T14893]  ? __warn.cold+0x110/0x210
  [  102.117461][T14893]  ? folio_lruvec_lock_irqsave+0x10e/0x170
  [  102.118667][T14893]  ? report_bug+0x1b9/0x320
  [  102.119571][T14893]  ? handle_bug+0x54/0x90
  [  102.120494][T14893]  ? exc_invalid_op+0x17/0x50
  [  102.121433][T14893]  ? asm_exc_invalid_op+0x1a/0x20
  [  102.122435][T14893]  ? __wake_up_klogd.part.0+0x76/0xd0
  [  102.123506][T14893]  ? dump_page+0x4f/0x60
  [  102.124352][T14893]  ? folio_lruvec_lock_irqsave+0x10e/0x170
  [  102.125500][T14893]  folio_batch_move_lru+0xd4/0x200
  [  102.126577][T14893]  ? __pfx_lru_add+0x10/0x10
  [  102.127505][T14893]  __folio_batch_add_and_move+0x391/0x720
  [  102.128633][T14893]  ? __pfx_lru_add+0x10/0x10
  [  102.129550][T14893]  folio_putback_lru+0x16/0x80
  [  102.130564][T14893]  migrate_device_finalize+0x9b/0x530
  [  102.131640][T14893]  dmirror_migrate_to_device.constprop.0+0x7c5/0xad0
  [  102.133047][T14893]  dmirror_fops_unlocked_ioctl+0x89b/0xc80

Likely, nothing else goes wrong: putting the last folio reference will
remove the folio from the LRU again.  So besides memcg complaining, adding
the folio to be freed to the LRU is just an unnecessary step.

The new flow resembles what we have in migrate_folio_move(): add the dst
to the lru, remove migration ptes, unlock and unref dst.

Link: https://lkml.kernel.org/r/20250210161317.717936-1-david@redhat.com
Fixes: 8763cb45ab96 ("mm/migrate: new memory migration helper for use with device memory")
Signed-off-by: David Hildenbrand <david@redhat.com>
Cc: Jérôme Glisse <jglisse@redhat.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
(cherry picked from commit 41cddf83d8b00f29fd105e7a0777366edc69a5cf)
Signed-off-by: David Hildenbrand <david@redhat.com>
---
 mm/migrate_device.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 180dbb99c320b..afe3b2d2e7b9d 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -854,20 +854,15 @@ void migrate_device_finalize(unsigned long *src_pfns,
 			dst = src;
 		}
 
+		if (!folio_is_zone_device(dst))
+			folio_add_lru(dst);
 		remove_migration_ptes(src, dst, false);
 		folio_unlock(src);
-
-		if (folio_is_zone_device(src))
-			folio_put(src);
-		else
-			folio_putback_lru(src);
+		folio_put(src);
 
 		if (dst != src) {
 			folio_unlock(dst);
-			if (folio_is_zone_device(dst))
-				folio_put(dst);
-			else
-				folio_putback_lru(dst);
+			folio_put(dst);
 		}
 	}
 }
-- 
2.51.0



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-09-25  8:23 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <2025022402-footprint-usher-aa6e@gregkh>
2025-09-25  8:23 ` [PATCH 6.1.y 0/2] mm/migrate_device: don't add folio to be freed to LRU in migrate_device_finalize() David Hildenbrand
2025-09-25  8:23   ` [PATCH 6.1.y 1/2] mm: migrate_device: use more folio " David Hildenbrand
2025-09-25  8:23   ` [PATCH 6.1.y 2/2] mm/migrate_device: don't add folio to be freed to LRU " David Hildenbrand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox