From: mpenttil@redhat.com
To: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org,
"Mika Penttilä" <mpenttil@redhat.com>,
"David Hildenbrand" <david@kernel.org>,
"Jason Gunthorpe" <jgg@nvidia.com>,
"Leon Romanovsky" <leonro@nvidia.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Balbir Singh" <balbirs@nvidia.com>, "Zi Yan" <ziy@nvidia.com>,
"Matthew Brost" <matthew.brost@intel.com>
Subject: [PATCH v7 2/6] mm: Add helper to convert HMM pfn to migrate pfn
Date: Mon, 30 Mar 2026 07:30:13 +0300 [thread overview]
Message-ID: <20260330043017.251808-3-mpenttil@redhat.com> (raw)
In-Reply-To: <20260330043017.251808-1-mpenttil@redhat.com>
From: Mika Penttilä <mpenttil@redhat.com>
The unified HMM/migrate_device pagewalk does the "collecting"
on the HMM side, so we need a helper to transfer pfns to the
migrate_vma world.
Cc: David Hildenbrand <david@kernel.org>
Cc: Jason Gunthorpe <jgg@nvidia.com>
Cc: Leon Romanovsky <leonro@nvidia.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Balbir Singh <balbirs@nvidia.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Suggested-by: Alistair Popple <apopple@nvidia.com>
Signed-off-by: Mika Penttilä <mpenttil@redhat.com>
---
include/linux/hmm.h | 18 ++++++++++++-
include/linux/migrate.h | 3 ++-
mm/migrate_device.c | 57 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/include/linux/hmm.h b/include/linux/hmm.h
index db75ffc949a7..9adc22b73533 100644
--- a/include/linux/hmm.h
+++ b/include/linux/hmm.h
@@ -13,6 +13,8 @@
struct mmu_interval_notifier;
+struct migrate_vma;
+
/*
* On output:
* 0 - The page is faultable and a future call with
@@ -27,6 +29,12 @@ struct mmu_interval_notifier;
* HMM_PFN_P2PDMA_BUS - Bus mapped P2P transfer
* HMM_PFN_DMA_MAPPED - Flag preserved on input-to-output transformation
* to mark that page is already DMA mapped
+ * HMM_PFN_MIGRATE - The entry is to be migrated. Note, HMM_PFN_MIGRATE
+ * alone without HMM_PFN_VALID denotes the
+ * empty page.
+ * This flag together with HMM_PFN_COMPOUND are
+ * indicators for migrate_hmm_range_setup() to
+ * setup the migrate pfns.
*
* On input:
* 0 - Return the current state of the page, do not fault it.
@@ -34,6 +42,8 @@ struct mmu_interval_notifier;
* will fail
* HMM_PFN_REQ_WRITE - The output must have HMM_PFN_WRITE or hmm_range_fault()
* will fail. Must be combined with HMM_PFN_REQ_FAULT.
+ * HMM_PFN_REQ_MIGRATE - For default_flags, request to migrate, according to
+ * hmm_range.migrate.flags
*/
enum hmm_pfn_flags {
/* Output fields and flags */
@@ -48,11 +58,15 @@ enum hmm_pfn_flags {
HMM_PFN_P2PDMA = 1UL << (BITS_PER_LONG - 5),
HMM_PFN_P2PDMA_BUS = 1UL << (BITS_PER_LONG - 6),
- HMM_PFN_ORDER_SHIFT = (BITS_PER_LONG - 11),
+ /* Migrate request */
+ HMM_PFN_MIGRATE = 1UL << (BITS_PER_LONG - 7),
+ HMM_PFN_COMPOUND = 1UL << (BITS_PER_LONG - 8),
+ HMM_PFN_ORDER_SHIFT = (BITS_PER_LONG - 13),
/* Input flags */
HMM_PFN_REQ_FAULT = HMM_PFN_VALID,
HMM_PFN_REQ_WRITE = HMM_PFN_WRITE,
+ HMM_PFN_REQ_MIGRATE = HMM_PFN_MIGRATE,
HMM_PFN_FLAGS = ~((1UL << HMM_PFN_ORDER_SHIFT) - 1),
};
@@ -107,6 +121,7 @@ static inline unsigned int hmm_pfn_to_map_order(unsigned long hmm_pfn)
* @default_flags: default flags for the range (write, read, ... see hmm doc)
* @pfn_flags_mask: allows to mask pfn flags so that only default_flags matter
* @dev_private_owner: owner of device private pages
+ * @migrate: structure for migrating a range of a VMA
*/
struct hmm_range {
struct mmu_interval_notifier *notifier;
@@ -117,6 +132,7 @@ struct hmm_range {
unsigned long default_flags;
unsigned long pfn_flags_mask;
void *dev_private_owner;
+ struct migrate_vma *migrate;
};
/*
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index d5af2b7f577b..425ab5242da0 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -3,6 +3,7 @@
#define _LINUX_MIGRATE_H
#include <linux/mm.h>
+#include <linux/hmm.h>
#include <linux/mempolicy.h>
#include <linux/migrate_mode.h>
#include <linux/hugetlb.h>
@@ -200,7 +201,7 @@ void migrate_device_pages(unsigned long *src_pfns, unsigned long *dst_pfns,
unsigned long npages);
void migrate_device_finalize(unsigned long *src_pfns,
unsigned long *dst_pfns, unsigned long npages);
-
+void migrate_hmm_range_setup(struct hmm_range *range);
#endif /* CONFIG_MIGRATION */
#endif /* _LINUX_MIGRATE_H */
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index 8079676c8f1f..a4062fd21490 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -1489,3 +1489,60 @@ int migrate_device_coherent_folio(struct folio *folio)
return 0;
return -EBUSY;
}
+
+/**
+ * migrate_hmm_range_setup() - prepare to migrate a range of memory
+ * @range: contains pointer to struct migrate_vma to be set up.
+ *
+ * When collecting has been done with hmm_range_fault(), this
+ * should be called next, and completes range->migrate by
+ * populating migrate->src[] and migrate->dst[]
+ * using range->hmm_pfns[].
+ * Also, migrate->cpages and migrate->npages get initialized.
+ * After migrate_hmm_range_setup(), range->migrate is good
+ * for the rest of the migrate_vma_* flow.
+ */
+void migrate_hmm_range_setup(struct hmm_range *range)
+{
+
+ struct migrate_vma *migrate = range->migrate;
+
+ if (!migrate)
+ return;
+
+ migrate->npages = (migrate->end - migrate->start) >> PAGE_SHIFT;
+ migrate->cpages = 0;
+
+ for (unsigned long i = 0; i < migrate->npages; i++) {
+
+ unsigned long pfn = range->hmm_pfns[i];
+
+ /*
+ * We are only interested in entries to be
+ * migrated.
+ */
+ if (!(pfn & HMM_PFN_MIGRATE)) {
+ migrate->src[i] = 0;
+ migrate->dst[i] = 0;
+ continue;
+ }
+
+ migrate->cpages++;
+
+ /* HMM_PFN_MIGRATE without HMM_PFN_VALID denotes the special zero page */
+ if (pfn & (HMM_PFN_VALID))
+ migrate->src[i] = migrate_pfn(page_to_pfn(hmm_pfn_to_page(pfn)))
+ | MIGRATE_PFN_MIGRATE;
+ else
+ migrate->src[i] = MIGRATE_PFN_MIGRATE;
+
+ migrate->src[i] |= (pfn & HMM_PFN_WRITE) ? MIGRATE_PFN_WRITE : 0;
+ migrate->src[i] |= (pfn & HMM_PFN_COMPOUND) ? MIGRATE_PFN_COMPOUND : 0;
+ migrate->dst[i] = 0;
+ }
+
+ if (migrate->cpages)
+ migrate_vma_unmap(migrate);
+
+}
+EXPORT_SYMBOL(migrate_hmm_range_setup);
--
2.50.0
next prev parent reply other threads:[~2026-03-30 4:30 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-30 4:30 [PATCH v7 0/6] Migrate on fault for device pages mpenttil
2026-03-30 4:30 ` [PATCH v7 1/6] mm:/Kconfig changes for migrate " mpenttil
2026-03-30 6:20 ` Christoph Hellwig
2026-03-30 4:30 ` mpenttil [this message]
2026-03-30 4:30 ` [PATCH v7 3/6] mm/hmm: do the plumbing for HMM to participate in migration mpenttil
2026-03-30 11:05 ` kernel test robot
2026-03-30 11:05 ` kernel test robot
2026-03-30 4:30 ` [PATCH v7 4/6] mm: setup device page migration in HMM pagewalk mpenttil
2026-03-30 4:30 ` [PATCH v7 5/6] mm: add new testcase for the migrate on fault case mpenttil
2026-03-30 6:21 ` Christoph Hellwig
2026-03-30 6:40 ` Mika Penttilä
2026-03-30 4:30 ` [PATCH v7 6/6] mm:/migrate_device.c: remove migrate_vma_collect_*() mpenttil
2026-03-30 6:22 ` Christoph Hellwig
2026-03-30 6:47 ` Mika Penttilä
-- strict thread matches above, loose matches on Subject: below --
2026-03-30 11:56 [RESEND PATCH v7 0/6] Migrate on fault for device pages mpenttil
2026-03-30 11:56 ` [PATCH v7 2/6] mm: Add helper to convert HMM pfn to migrate pfn mpenttil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260330043017.251808-3-mpenttil@redhat.com \
--to=mpenttil@redhat.com \
--cc=apopple@nvidia.com \
--cc=balbirs@nvidia.com \
--cc=david@kernel.org \
--cc=jgg@nvidia.com \
--cc=leonro@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=matthew.brost@intel.com \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.