Skip to content

Commit 795dc0e

Browse files
committed
mm/migrate: Add migrate_device_pfns
JIRA: https://issues.redhat.com/browse/RHEL-113204 commit a14fa8e Author: Matthew Brost <matthew.brost@intel.com> Date: Wed Mar 5 17:26:27 2025 -0800 mm/migrate: Add migrate_device_pfns Add migrate_device_pfns which prepares an array of pre-populated device pages for migration. This is needed for eviction of known set of non-contiguous devices pages to cpu pages which is a common case for SVM in DRM drivers using TTM. v2: - s/migrate_device_vma_range/migrate_device_prepopulated_range - Drop extra mmu invalidation (Vetter) v3: - s/migrate_device_prepopulated_range/migrate_device_pfns (Alistar) - Use helper to lock device pages (Alistar) - Update commit message with why this is required (Alistar) Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Alistair Popple <apopple@nvidia.com> Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250306012657.3505757-3-matthew.brost@intel.com Signed-off-by: José Expósito <jexposit@redhat.com>
1 parent 6530343 commit 795dc0e

File tree

2 files changed

+38
-15
lines changed

2 files changed

+38
-15
lines changed

include/linux/migrate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ void migrate_vma_pages(struct migrate_vma *migrate);
222222
void migrate_vma_finalize(struct migrate_vma *migrate);
223223
int migrate_device_range(unsigned long *src_pfns, unsigned long start,
224224
unsigned long npages);
225+
int migrate_device_pfns(unsigned long *src_pfns, unsigned long npages);
225226
void migrate_device_pages(unsigned long *src_pfns, unsigned long *dst_pfns,
226227
unsigned long npages);
227228
void migrate_device_finalize(unsigned long *src_pfns,

mm/migrate_device.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,22 @@ void migrate_vma_finalize(struct migrate_vma *migrate)
870870
}
871871
EXPORT_SYMBOL(migrate_vma_finalize);
872872

873+
static unsigned long migrate_device_pfn_lock(unsigned long pfn)
874+
{
875+
struct folio *folio;
876+
877+
folio = folio_get_nontail_page(pfn_to_page(pfn));
878+
if (!folio)
879+
return 0;
880+
881+
if (!folio_trylock(folio)) {
882+
folio_put(folio);
883+
return 0;
884+
}
885+
886+
return migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
887+
}
888+
873889
/**
874890
* migrate_device_range() - migrate device private pfns to normal memory.
875891
* @src_pfns: array large enough to hold migrating source device private pfns.
@@ -894,29 +910,35 @@ int migrate_device_range(unsigned long *src_pfns, unsigned long start,
894910
{
895911
unsigned long i, pfn;
896912

897-
for (pfn = start, i = 0; i < npages; pfn++, i++) {
898-
struct folio *folio;
913+
for (pfn = start, i = 0; i < npages; pfn++, i++)
914+
src_pfns[i] = migrate_device_pfn_lock(pfn);
899915

900-
folio = folio_get_nontail_page(pfn_to_page(pfn));
901-
if (!folio) {
902-
src_pfns[i] = 0;
903-
continue;
904-
}
916+
migrate_device_unmap(src_pfns, npages, NULL);
905917

906-
if (!folio_trylock(folio)) {
907-
src_pfns[i] = 0;
908-
folio_put(folio);
909-
continue;
910-
}
918+
return 0;
919+
}
920+
EXPORT_SYMBOL(migrate_device_range);
911921

912-
src_pfns[i] = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
913-
}
922+
/**
923+
* migrate_device_pfns() - migrate device private pfns to normal memory.
924+
* @src_pfns: pre-popluated array of source device private pfns to migrate.
925+
* @npages: number of pages to migrate.
926+
*
927+
* Similar to migrate_device_range() but supports non-contiguous pre-popluated
928+
* array of device pages to migrate.
929+
*/
930+
int migrate_device_pfns(unsigned long *src_pfns, unsigned long npages)
931+
{
932+
unsigned long i;
933+
934+
for (i = 0; i < npages; i++)
935+
src_pfns[i] = migrate_device_pfn_lock(src_pfns[i]);
914936

915937
migrate_device_unmap(src_pfns, npages, NULL);
916938

917939
return 0;
918940
}
919-
EXPORT_SYMBOL(migrate_device_range);
941+
EXPORT_SYMBOL(migrate_device_pfns);
920942

921943
/*
922944
* Migrate a device coherent folio back to normal memory. The caller should have

0 commit comments

Comments
 (0)