On Mon, 8 Sep 2025 10:04:38 +1000 Balbir Singh <[email protected]> wrote:
> Extend migrate_vma_collect_pmd() to handle partially mapped large > folios that require splitting before migration can proceed. > > During PTE walk in the collection phase, if a large folio is only > partially mapped in the migration range, it must be split to ensure > the folio is correctly migrated. > > Signed-off-by: Balbir Singh <[email protected]> > --- > mm/migrate_device.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 94 insertions(+) > > diff --git a/mm/migrate_device.c b/mm/migrate_device.c > index abd9f6850db6..f45ef182287d 100644 > --- a/mm/migrate_device.c > +++ b/mm/migrate_device.c > @@ -54,6 +54,53 @@ static int migrate_vma_collect_hole(unsigned long start, > return 0; > } > > +/** > + * migrate_vma_split_folio() - Helper function to split a THP folio > + * @folio: the folio to split > + * @fault_page: struct page associated with the fault if any > + * > + * Returns 0 on success > + */ > +static int migrate_vma_split_folio(struct folio *folio, > + struct page *fault_page) > +{ > + int ret; > + struct folio *fault_folio = fault_page ? page_folio(fault_page) : NULL; > + struct folio *new_fault_folio = NULL; > + > + if (folio != fault_folio) { > + folio_get(folio); > + folio_lock(folio); > + } Can fault_folio ever be non-null and different from folio? Apologies for not knowing the lock ordering rules but this jumps out. > + > + ret = split_folio(folio); > + if (ret) { > + if (folio != fault_folio) { > + folio_unlock(folio); > + folio_put(folio); > + } > + return ret; > + } > + > + new_fault_folio = fault_page ? page_folio(fault_page) : NULL; > + > + /* > + * Ensure the lock is held on the correct > + * folio after the split > + */ > + if (!new_fault_folio) { > + folio_unlock(folio); > + folio_put(folio); > + } else if (folio != new_fault_folio) { > + folio_get(new_fault_folio); > + folio_lock(new_fault_folio); > + folio_unlock(folio); > + folio_put(folio); > + } Same question here, do we need trylocks? -chris
