On Mon, Jan 05, 2026 at 12:18:27PM +0100, Francois Dugast wrote: > This code was written by Matt Brost. This is a placeholder until his > patch is available. >
Patch looks good to me, change myself to author and use this commit message: drm/xe: Correct cpages calculation for migrate_vma_setup cpages returned from migrate_vma_setup represents the total number of individual pages found, not the number of 4K pages. The math in drm_pagemap_migrate_to_devmem for npages is based on the number of 4K pages, so cpages != npages can fail even if the entire memory range is found in migrate_vma_setup (e.g., when a single 2M page is found). Add drm_pagemap_cpages, which converts cpages to the number of 4K pages found. > Cc: Matthew Brost <[email protected]> > Signed-off-by: Francois Dugast <[email protected]> > --- > drivers/gpu/drm/drm_pagemap.c | 36 ++++++++++++++++++++++++++++++++++- > 1 file changed, 35 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c > index db3795f03aca..05e708730132 100644 > --- a/drivers/gpu/drm/drm_pagemap.c > +++ b/drivers/gpu/drm/drm_pagemap.c > @@ -452,6 +452,39 @@ static int drm_pagemap_migrate_range(struct > drm_pagemap_devmem *devmem, > return ret; > } > > +/** > + * drm_pagemap_cpages() - Count collected pages > + * @migrate_pfn: Array of migrate_pfn entries to account > + * @npages: Number of entries in @migrate_pfn > + * > + * Compute the total number of minimum-sized pages represented by the > + * collected entries in @migrate_pfn. The total is derived from the > + * order encoded in each entry. > + * > + * Return: Total number of minimum-sized pages. > + */ > +static int drm_pagemap_cpages(unsigned long *migrate_pfn, unsigned long > npages) > +{ > + unsigned long i, cpages = 0; > + > + for (i = 0; i < npages;) { > + struct page *page = migrate_pfn_to_page(migrate_pfn[i]); > + struct folio *folio; > + unsigned int order = 0; > + > + if (!page) > + goto next; > + > + folio = page_folio(page); > + order = folio_order(folio); > + cpages += NR_PAGES(order); > +next: > + i += NR_PAGES(order); > + } > + > + return cpages; > +} > + > /** > * drm_pagemap_migrate_to_devmem() - Migrate a struct mm_struct range to > device memory > * @devmem_allocation: The device memory allocation to migrate to. > @@ -554,7 +587,8 @@ int drm_pagemap_migrate_to_devmem(struct > drm_pagemap_devmem *devmem_allocation, > goto err_free; > } > > - if (migrate.cpages != npages) { > + if (migrate.cpages != npages && > + drm_pagemap_cpages(migrate.src, npages) != npages) { > /* > * Some pages to migrate. But we want to migrate all or > * nothing. Raced or unknown device pages. > -- > 2.43.0 >
