[PATCH v5 08/13] mm: Add softleaf support for device private migration entries

Jordan Niethe
2026-01-30T11:12:17Z

Add equivalent softleaf entries for the device private migration
swap entries:

- SWP_MIGRATION_DEVICE_READ -> SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ
- SWP_MIGRATION_DEVICE_WRITE -> SOFTLEAF_MIGRATION_DEVICE_PRIVATE_WRITE
- SWP_MIGRATION_DEVICE_READ_EXCLUSIVE -> SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ_EXCLUSIVE

As with their SWP_MIGRATION_DEVICE_xxx kin, the
SOFTLEAF_MIGRATION_DEVICE_PRIVATE_xxx types are used as specializations
of the SWP_MIGRATION_DEVICE_xxx types.

The new entry types have the following relationships:

- SOFTLEAF_MIGRATION_DEVICE_READ is-a SOFTLEAF_MIGRATION_READ
- SOFTLEAF_MIGRATION_READ !is-a SOFTLEAF_MIGRATION_DEVICE_READ

Update the existing softleaf_is_migration_xxx() predicates to reflect
this relationship.

It is possible to distinguish the between a
SOFTLEAF_MIGRATION_DEVICE__xxx and a SOFTLEAF_MIGRATION_xxx type using
the softleaf_is_migration_device_private_xxx() predicates.

In practice, the only reason for introducing this new type is so we know
when to not call pfn_to_page() on the swap entry offset once the device
private pages are removed from the physical address space. That is the
only time that the difference matters.

Creating these new entries will occur in a subsequent patch.

Signed-off-by: Jordan Niethe <jniethe@nvidia.com>
---
v3:
- Separated from previous patch
- s/SOFTLEAF_MIGRATION_DEVICE_/SOFTLEAF_MIGRATION_DEVICE_PRIVATE_/
- Update comment for softleaf_is_migration_read()
---
include/linux/leafops.h | 90 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 80 insertions(+), 10 deletions(-)

diff --git a/include/linux/leafops.h b/include/linux/leafops.h
index 52a1af3eb954..60681ada7b8e 100644
--- a/include/linux/leafops.h
+++ b/include/linux/leafops.h
@@ -28,6 +28,9 @@ enum softleaf_type {
SOFTLEAF_DEVICE_PRIVATE_READ,
SOFTLEAF_DEVICE_PRIVATE_WRITE,
SOFTLEAF_DEVICE_EXCLUSIVE,
+ SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ,
+ SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ_EXCLUSIVE,
+ SOFTLEAF_MIGRATION_DEVICE_PRIVATE_WRITE,
/* H/W posion types. */
SOFTLEAF_HWPOISON,
/* Marker types. */
@@ -165,6 +168,12 @@ static inline enum softleaf_type softleaf_type(softleaf_t entry)
return SOFTLEAF_DEVICE_PRIVATE_READ;
case SWP_DEVICE_EXCLUSIVE:
return SOFTLEAF_DEVICE_EXCLUSIVE;
+ case SWP_MIGRATION_DEVICE_READ:
+ return SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ;
+ case SWP_MIGRATION_DEVICE_WRITE:
+ return SOFTLEAF_MIGRATION_DEVICE_PRIVATE_WRITE;
+ case SWP_MIGRATION_DEVICE_READ_EXCLUSIVE:
+ return SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ_EXCLUSIVE;
#endif
#ifdef CONFIG_MEMORY_FAILURE
case SWP_HWPOISON:
@@ -190,28 +199,88 @@ static inline bool softleaf_is_swap(softleaf_t entry)
return softleaf_type(entry) == SOFTLEAF_SWAP;
}

+/**
+ * softleaf_is_migration_device_private() - Is this leaf entry a migration
+ * device private entry?
+ * @entry: Leaf entry.
+ *
+ * Returns: true if the leaf entry is a device private entry, otherwise false.
+ */
+static inline bool softleaf_is_migration_device_private(softleaf_t entry)
+{
+ switch (softleaf_type(entry)) {
+ case SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ:
+ case SOFTLEAF_MIGRATION_DEVICE_PRIVATE_WRITE:
+ case SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ_EXCLUSIVE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * softleaf_is_migration_device_private_write() - Is this leaf entry a writable
+ * device private migration entry?
+ * @entry: Leaf entry.
+ *
+ * Returns: true if the leaf entry is a writable device private migration entry,
+ * otherwise false.
+ */
+static inline bool softleaf_is_migration_device_private_write(softleaf_t entry)
+{
+ return softleaf_type(entry) == SOFTLEAF_MIGRATION_DEVICE_PRIVATE_WRITE;
+}
+
+/**
+ * softleaf_is_migration_device_private_read() - Is this leaf entry a readable
+ * device private migration entry?
+ * @entry: Leaf entry.
+ *
+ * Returns: true if the leaf entry is an readable device private migration
+ * entry, otherwise false.
+ */
+static inline bool softleaf_is_migration_device_private_read(softleaf_t entry)
+{
+ return softleaf_type(entry) == SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ;
+}
+
+/**
+ * softleaf_is_migration_read_exclusive() - Is this leaf entry an exclusive
+ * readable device private migration entry?
+ * @entry: Leaf entry.
+ *
+ * Returns: true if the leaf entry is an exclusive readable device private
+ * migration entry, otherwise false.
+ */
+static inline bool softleaf_is_migration_device_private_read_exclusive(softleaf_t entry)
+{
+ return softleaf_type(entry) == SOFTLEAF_MIGRATION_DEVICE_PRIVATE_READ_EXCLUSIVE;
+}
+
/**
* softleaf_is_migration_write() - Is this leaf entry a writable migration entry?
* @entry: Leaf entry.
*
- * Returns: true if the leaf entry is a writable migration entry, otherwise
- * false.
+ * Returns: true if the leaf entry is a writable migration entry or a writable
+ * device private migration entry, otherwise false.
*/
static inline bool softleaf_is_migration_write(softleaf_t entry)
{
- return softleaf_type(entry) == SOFTLEAF_MIGRATION_WRITE;
+ return softleaf_type(entry) == SOFTLEAF_MIGRATION_WRITE ||
+ softleaf_is_migration_device_private_write(entry);
}

/**
* softleaf_is_migration_read() - Is this leaf entry a readable migration entry?
* @entry: Leaf entry.
*
- * Returns: true if the leaf entry is a readable migration entry, otherwise
- * false.
+ * Returns: true if the leaf entry is a readable migration entry or a readable
+ * device private migration entry, otherwise false.
*/
static inline bool softleaf_is_migration_read(softleaf_t entry)
{
- return softleaf_type(entry) == SOFTLEAF_MIGRATION_READ;
+ return softleaf_type(entry) == SOFTLEAF_MIGRATION_READ ||
+ softleaf_is_migration_device_private_read(entry);
}

/**
@@ -219,12 +288,13 @@ static inline bool softleaf_is_migration_read(softleaf_t entry)
* readable migration entry?
* @entry: Leaf entry.
*
- * Returns: true if the leaf entry is an exclusive readable migration entry,
- * otherwise false.
+ * Returns: true if the leaf entry is an exclusive readable migration entry or
+ * exclusive readable device private migration entry, otherwise false.
*/
static inline bool softleaf_is_migration_read_exclusive(softleaf_t entry)
{
- return softleaf_type(entry) == SOFTLEAF_MIGRATION_READ_EXCLUSIVE;
+ return softleaf_type(entry) == SOFTLEAF_MIGRATION_READ_EXCLUSIVE ||
+ softleaf_is_migration_device_private_read_exclusive(entry);
}

/**
@@ -241,7 +311,7 @@ static inline bool softleaf_is_migration(softleaf_t entry)
case SOFTLEAF_MIGRATION_WRITE:
return true;
default:
- return false;
+ return softleaf_is_migration_device_private(entry);
}
}

--
2.34.1