[PATCH v13 05/11] mm/hmm: implement folio split for migrate needs in HMM pagewalk
From: mpenttil
Date: Tue Aug 04 2026 - 00:31:33 EST
From: Mika Penttilä <mpenttil@xxxxxxxxxx>
Implement the helper to split PMD size folios during pagewalk.
Splitting is needed if the start and end addresses are
not PMD aligned, or setting up pmd migration entry fails.
Cc: David Hildenbrand <david@xxxxxxxxxx>
Cc: Jason Gunthorpe <jgg@xxxxxxxxxx>
Cc: Leon Romanovsky <leonro@xxxxxxxxxx>
Cc: Alistair Popple <apopple@xxxxxxxxxx>
Cc: Balbir Singh <balbirs@xxxxxxxxxx>
Cc: Zi Yan <ziy@xxxxxxxxxx>
Cc: Matthew Brost <matthew.brost@xxxxxxxxx>
Suggested-by: Alistair Popple <apopple@xxxxxxxxxx>
Signed-off-by: Mika Penttilä <mpenttil@xxxxxxxxxx>
---
mm/hmm.c | 47 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 44 insertions(+), 3 deletions(-)
diff --git a/mm/hmm.c b/mm/hmm.c
index 75e19be6ef76..3621d1df51d3 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -511,10 +511,51 @@ static int hmm_vma_walk_split(pmd_t *pmdp,
unsigned long addr,
struct mm_walk *walk)
{
- // TODO : implement split
- return 0;
-}
+ struct hmm_vma_walk *hmm_vma_walk = walk->private;
+ struct hmm_range *range = hmm_vma_walk->range;
+ struct migrate_vma *migrate = range->migrate;
+ struct folio *folio, *fault_folio;
+ spinlock_t *ptl;
+ int ret = 0;
+
+ HMM_ASSERT_UNLOCKED(hmm_vma_walk);
+
+ fault_folio = (migrate && migrate->fault_page) ?
+ page_folio(migrate->fault_page) : NULL;
+
+ ptl = pmd_lock(walk->mm, pmdp);
+ if (unlikely(!pmd_trans_huge(*pmdp))) {
+ spin_unlock(ptl);
+ goto out;
+ }
+ folio = pmd_folio(*pmdp);
+ if (is_huge_zero_folio(folio)) {
+ spin_unlock(ptl);
+ split_huge_pmd(walk->vma, pmdp, addr);
+ } else {
+ folio_get(folio);
+ spin_unlock(ptl);
+
+ if (folio != fault_folio) {
+ if (unlikely(!folio_trylock(folio))) {
+ folio_put(folio);
+ ret = -EBUSY;
+ goto out;
+ }
+ } else {
+ folio_put(folio);
+ }
+
+ ret = split_folio(folio);
+ if (fault_folio != folio) {
+ folio_unlock(folio);
+ folio_put(folio);
+ }
+ }
+out:
+ return ret;
+}
#else
static int hmm_vma_handle_migrate_prepare_pmd(const struct mm_walk *walk,
pmd_t *pmdp,
--
2.55.0