lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1371381f755a8f04a8228e52c36ddfde72949b57.1742099301.git-series.apopple@nvidia.com>
Date: Sun, 16 Mar 2025 15:29:25 +1100
From: Alistair Popple <apopple@...dia.com>
To: linux-mm@...ck.org
Cc: linux-fsdevel@...r.kernel.org,
	linux-kernel@...r.kernel.org,
	Alistair Popple <apopple@...dia.com>
Subject: [PATCH RFC 2/6] mm/migrate: Support file-backed pages with migrate_vma

This adds support for migrating file backed pages with the migrate_vma
calls. Note that this does not support migrating file backed pages
to device private pages, only CPU addressable memory. However add the
extra refcount argument to support faulting on device privatge pages
in future.

Signed-off-by: Alistair Popple <apopple@...dia.com>

---

Known issues with the RFC:

 - Some filesystems (eg. xfs, nfs) can insert higher order compound
   pages in the pagecache. Migration will fail for such pages.
---
 include/linux/migrate.h |  4 ++++
 mm/migrate.c            | 19 +++++++++++--------
 mm/migrate_device.c     | 11 +++++++++--
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 29919fa..9023d0f 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -222,6 +222,10 @@ struct migrate_vma {
 	struct page		*fault_page;
 };
 
+int fallback_migrate_folio(struct address_space *mapping,
+		struct folio *dst, struct folio *src, enum migrate_mode mode,
+		int extra_count);
+
 int migrate_vma_setup(struct migrate_vma *args);
 void migrate_vma_pages(struct migrate_vma *migrate);
 void migrate_vma_finalize(struct migrate_vma *migrate);
diff --git a/mm/migrate.c b/mm/migrate.c
index fb19a18..11fca43 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -749,9 +749,10 @@ EXPORT_SYMBOL(folio_migrate_flags);
 
 static int __migrate_folio(struct address_space *mapping, struct folio *dst,
 			   struct folio *src, void *src_private,
-			   enum migrate_mode mode)
+			   enum migrate_mode mode, int extra_count)
 {
-	int rc, expected_count = folio_expected_refs(mapping, src);
+	int rc;
+	int expected_count = folio_expected_refs(mapping, src) + extra_count;
 
 	/* Check whether src does not have extra refs before we do more work */
 	if (folio_ref_count(src) != expected_count)
@@ -788,7 +789,7 @@ int migrate_folio(struct address_space *mapping, struct folio *dst,
 		  struct folio *src, enum migrate_mode mode)
 {
 	BUG_ON(folio_test_writeback(src));	/* Writeback must be complete */
-	return __migrate_folio(mapping, dst, src, NULL, mode);
+	return __migrate_folio(mapping, dst, src, NULL, mode, 0);
 }
 EXPORT_SYMBOL(migrate_folio);
 
@@ -942,7 +943,8 @@ EXPORT_SYMBOL_GPL(buffer_migrate_folio_norefs);
 int filemap_migrate_folio(struct address_space *mapping,
 		struct folio *dst, struct folio *src, enum migrate_mode mode)
 {
-	return __migrate_folio(mapping, dst, src, folio_get_private(src), mode);
+	return __migrate_folio(mapping, dst, src,
+			folio_get_private(src), mode, 0);
 }
 EXPORT_SYMBOL_GPL(filemap_migrate_folio);
 
@@ -990,8 +992,9 @@ static int writeout(struct address_space *mapping, struct folio *folio)
 /*
  * Default handling if a filesystem does not provide a migration function.
  */
-static int fallback_migrate_folio(struct address_space *mapping,
-		struct folio *dst, struct folio *src, enum migrate_mode mode)
+int fallback_migrate_folio(struct address_space *mapping,
+		struct folio *dst, struct folio *src, enum migrate_mode mode,
+		int extra_count)
 {
 	if (folio_test_dirty(src)) {
 		/* Only writeback folios in full synchronous migration */
@@ -1011,7 +1014,7 @@ static int fallback_migrate_folio(struct address_space *mapping,
 	if (!filemap_release_folio(src, GFP_KERNEL))
 		return mode == MIGRATE_SYNC ? -EAGAIN : -EBUSY;
 
-	return migrate_folio(mapping, dst, src, mode);
+	return __migrate_folio(mapping, dst, src, NULL, mode, extra_count);
 }
 
 /*
@@ -1052,7 +1055,7 @@ static int move_to_new_folio(struct folio *dst, struct folio *src,
 			rc = mapping->a_ops->migrate_folio(mapping, dst, src,
 								mode);
 		else
-			rc = fallback_migrate_folio(mapping, dst, src, mode);
+			rc = fallback_migrate_folio(mapping, dst, src, mode, 0);
 	} else {
 		const struct movable_operations *mops;
 
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index afc033b..7bcc177 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -763,11 +763,18 @@ static void __migrate_device_pages(unsigned long *src_pfns,
 
 		if (migrate && migrate->fault_page == page)
 			extra_cnt = 1;
-		r = folio_migrate_mapping(mapping, newfolio, folio, extra_cnt);
+		if (mapping)
+			r = fallback_migrate_folio(mapping, newfolio, folio,
+						MIGRATE_SYNC, extra_cnt);
+		else
+			r = folio_migrate_mapping(mapping, newfolio, folio,
+						extra_cnt);
 		if (r != MIGRATEPAGE_SUCCESS)
 			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
-		else
+		else if (!mapping)
 			folio_migrate_flags(newfolio, folio);
+		else
+			folio->mapping = NULL;
 	}
 
 	if (notified)
-- 
git-series 0.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ