From: Francois Dugast <francois.dugast@intel.com>
To: Matthew Brost <matthew.brost@intel.com>
Cc: <intel-xe@lists.freedesktop.org>,
<dri-devel@lists.freedesktop.org>, <leonro@nvidia.com>,
<jgg@ziepe.ca>, <thomas.hellstrom@linux.intel.com>,
<himal.prasad.ghimiray@intel.com>
Subject: Re: [PATCH v5 4/5] drm/pagemap: Split drm_pagemap_migrate_map_pages into device / system
Date: Thu, 2 Apr 2026 16:12:02 +0200 [thread overview]
Message-ID: <ac55MqY8MucJK6_V@fdugast-desk> (raw)
In-Reply-To: <20260219201057.1010391-5-matthew.brost@intel.com>
On Thu, Feb 19, 2026 at 12:10:56PM -0800, Matthew Brost wrote:
> Split drm_pagemap_migrate_map_pages into device / system helpers clearly
> seperating these operations. Will help with upcoming changes to split
> IOVA allocation steps.
Side effect is that it makes the code a lot more readable. A couple of
nits below.
Reviewed-by: Francois Dugast <francois.dugast@intel.com>
>
> Signed-off-by: Matthew Brost <matthew.brost@intel.com>
>
> ---
> v5:
> - s/map_device_pages/map_device_private_pages (Thomas)
> - Fix map_system_pages kernel doc (Thomas)
> ---
> drivers/gpu/drm/drm_pagemap.c | 150 ++++++++++++++++++++++------------
> 1 file changed, 100 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
> index 32535ab01c0f..ef8b9c69d1d4 100644
> --- a/drivers/gpu/drm/drm_pagemap.c
> +++ b/drivers/gpu/drm/drm_pagemap.c
> @@ -205,7 +205,8 @@ static void drm_pagemap_get_devmem_page(struct page *page,
> }
>
> /**
> - * drm_pagemap_migrate_map_pages() - Map migration pages for GPU SVM migration
> + * drm_pagemap_migrate_map_device_private_pages() - Map device privaet migration
s/privaet/private/
> + * pages for GPU SVM migration
> * @dev: The device performing the migration.
> * @local_dpagemap: The drm_pagemap local to the migrating device.
> * @pagemap_addr: Array to store DMA information corresponding to mapped pages.
> @@ -221,19 +222,22 @@ static void drm_pagemap_get_devmem_page(struct page *page,
> *
> * Returns: 0 on success, -EFAULT if an error occurs during mapping.
> */
> -static int drm_pagemap_migrate_map_pages(struct device *dev,
> - struct drm_pagemap *local_dpagemap,
> - struct drm_pagemap_addr *pagemap_addr,
> - unsigned long *migrate_pfn,
> - unsigned long npages,
> - enum dma_data_direction dir,
> - const struct drm_pagemap_migrate_details *mdetails)
> +static int
> +drm_pagemap_migrate_map_device_private_pages(struct device *dev,
> + struct drm_pagemap *local_dpagemap,
> + struct drm_pagemap_addr *pagemap_addr,
> + unsigned long *migrate_pfn,
> + unsigned long npages,
> + enum dma_data_direction dir,
> + const struct drm_pagemap_migrate_details *mdetails)
> {
> unsigned long num_peer_pages = 0, num_local_pages = 0, i;
>
> for (i = 0; i < npages;) {
> struct page *page = migrate_pfn_to_page(migrate_pfn[i]);
> - dma_addr_t dma_addr;
> + struct drm_pagemap_zdd *zdd;
> + struct drm_pagemap *dpagemap;
> + struct drm_pagemap_addr addr;
> struct folio *folio;
> unsigned int order = 0;
>
> @@ -243,36 +247,26 @@ static int drm_pagemap_migrate_map_pages(struct device *dev,
> folio = page_folio(page);
> order = folio_order(folio);
>
> - if (is_device_private_page(page)) {
> - struct drm_pagemap_zdd *zdd = drm_pagemap_page_zone_device_data(page);
> - struct drm_pagemap *dpagemap = zdd->dpagemap;
> - struct drm_pagemap_addr addr;
> -
> - if (dpagemap == local_dpagemap) {
> - if (!mdetails->can_migrate_same_pagemap)
> - goto next;
> + WARN_ON_ONCE(!is_device_private_page(page));
Another nit: could we move this line ^ above that one:
folio = page_folio(page);
so that the check is the first thing we do with that page, and also to
have a bit more symmetry with +drm_pagemap_migrate_map_system_pages().
Francois
>
> - num_local_pages += NR_PAGES(order);
> - } else {
> - num_peer_pages += NR_PAGES(order);
> - }
> + zdd = drm_pagemap_page_zone_device_data(page);
> + dpagemap = zdd->dpagemap;
>
> - addr = dpagemap->ops->device_map(dpagemap, dev, page, order, dir);
> - if (dma_mapping_error(dev, addr.addr))
> - return -EFAULT;
> + if (dpagemap == local_dpagemap) {
> + if (!mdetails->can_migrate_same_pagemap)
> + goto next;
>
> - pagemap_addr[i] = addr;
> + num_local_pages += NR_PAGES(order);
> } else {
> - dma_addr = dma_map_page(dev, page, 0, page_size(page), dir);
> - if (dma_mapping_error(dev, dma_addr))
> - return -EFAULT;
> -
> - pagemap_addr[i] =
> - drm_pagemap_addr_encode(dma_addr,
> - DRM_INTERCONNECT_SYSTEM,
> - order, dir);
> + num_peer_pages += NR_PAGES(order);
> }
>
> + addr = dpagemap->ops->device_map(dpagemap, dev, page, order, dir);
> + if (dma_mapping_error(dev, addr.addr))
> + return -EFAULT;
> +
> + pagemap_addr[i] = addr;
> +
> next:
> i += NR_PAGES(order);
> }
> @@ -287,6 +281,60 @@ static int drm_pagemap_migrate_map_pages(struct device *dev,
> return 0;
> }
>
> +/**
> + * drm_pagemap_migrate_map_system_pages() - Map system or device coherent
> + * migration pages for GPU SVM migration
> + * @dev: The device performing the migration.
> + * @pagemap_addr: Array to store DMA information corresponding to mapped pages.
> + * @migrate_pfn: Array of page frame numbers of system pages or peer pages to map.
> + * @npages: Number of system or device coherent pages to map.
> + * @dir: Direction of data transfer (e.g., DMA_BIDIRECTIONAL)
> + *
> + * This function maps pages of memory for migration usage in GPU SVM. It
> + * iterates over each page frame number provided in @migrate_pfn, maps the
> + * corresponding page, and stores the DMA address in the provided @dma_addr
> + * array.
> + *
> + * Returns: 0 on success, -EFAULT if an error occurs during mapping.
> + */
> +static int
> +drm_pagemap_migrate_map_system_pages(struct device *dev,
> + struct drm_pagemap_addr *pagemap_addr,
> + unsigned long *migrate_pfn,
> + unsigned long npages,
> + enum dma_data_direction dir)
> +{
> + unsigned long i;
> +
> + for (i = 0; i < npages;) {
> + struct page *page = migrate_pfn_to_page(migrate_pfn[i]);
> + dma_addr_t dma_addr;
> + struct folio *folio;
> + unsigned int order = 0;
> +
> + if (!page)
> + goto next;
> +
> + WARN_ON_ONCE(is_device_private_page(page));
> + folio = page_folio(page);
> + order = folio_order(folio);
> +
> + dma_addr = dma_map_page(dev, page, 0, page_size(page), dir);
> + if (dma_mapping_error(dev, dma_addr))
> + return -EFAULT;
> +
> + pagemap_addr[i] =
> + drm_pagemap_addr_encode(dma_addr,
> + DRM_INTERCONNECT_SYSTEM,
> + order, dir);
> +
> +next:
> + i += NR_PAGES(order);
> + }
> +
> + return 0;
> +}
> +
> /**
> * drm_pagemap_migrate_unmap_pages() - Unmap pages previously mapped for GPU SVM migration
> * @dev: The device for which the pages were mapped
> @@ -347,9 +395,13 @@ drm_pagemap_migrate_remote_to_local(struct drm_pagemap_devmem *devmem,
> const struct drm_pagemap_migrate_details *mdetails)
>
> {
> - int err = drm_pagemap_migrate_map_pages(remote_device, remote_dpagemap,
> - pagemap_addr, local_pfns,
> - npages, DMA_FROM_DEVICE, mdetails);
> + int err = drm_pagemap_migrate_map_device_private_pages(remote_device,
> + remote_dpagemap,
> + pagemap_addr,
> + local_pfns,
> + npages,
> + DMA_FROM_DEVICE,
> + mdetails);
>
> if (err)
> goto out;
> @@ -368,12 +420,11 @@ drm_pagemap_migrate_sys_to_dev(struct drm_pagemap_devmem *devmem,
> struct page *local_pages[],
> struct drm_pagemap_addr pagemap_addr[],
> unsigned long npages,
> - const struct drm_pagemap_devmem_ops *ops,
> - const struct drm_pagemap_migrate_details *mdetails)
> + const struct drm_pagemap_devmem_ops *ops)
> {
> - int err = drm_pagemap_migrate_map_pages(devmem->dev, devmem->dpagemap,
> - pagemap_addr, sys_pfns, npages,
> - DMA_TO_DEVICE, mdetails);
> + int err = drm_pagemap_migrate_map_system_pages(devmem->dev,
> + pagemap_addr, sys_pfns,
> + npages, DMA_TO_DEVICE);
>
> if (err)
> goto out;
> @@ -437,7 +488,7 @@ static int drm_pagemap_migrate_range(struct drm_pagemap_devmem *devmem,
> &pages[last->start],
> &pagemap_addr[last->start],
> cur->start - last->start,
> - last->ops, mdetails);
> + last->ops);
>
> out:
> *last = *cur;
> @@ -942,7 +993,6 @@ EXPORT_SYMBOL(drm_pagemap_put);
> int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
> {
> const struct drm_pagemap_devmem_ops *ops = devmem_allocation->ops;
> - struct drm_pagemap_migrate_details mdetails = {};
> unsigned long npages, mpages = 0;
> struct page **pages;
> unsigned long *src, *dst;
> @@ -981,10 +1031,10 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
> if (err || !mpages)
> goto err_finalize;
>
> - err = drm_pagemap_migrate_map_pages(devmem_allocation->dev,
> - devmem_allocation->dpagemap, pagemap_addr,
> - dst, npages, DMA_FROM_DEVICE,
> - &mdetails);
> + err = drm_pagemap_migrate_map_system_pages(devmem_allocation->dev,
> + pagemap_addr,
> + dst, npages,
> + DMA_FROM_DEVICE);
> if (err)
> goto err_finalize;
>
> @@ -1045,7 +1095,6 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
> MIGRATE_VMA_SELECT_DEVICE_COHERENT,
> .fault_page = page,
> };
> - struct drm_pagemap_migrate_details mdetails = {};
> struct drm_pagemap_zdd *zdd;
> const struct drm_pagemap_devmem_ops *ops;
> struct device *dev = NULL;
> @@ -1103,8 +1152,9 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
> if (err)
> goto err_finalize;
>
> - err = drm_pagemap_migrate_map_pages(dev, zdd->dpagemap, pagemap_addr, migrate.dst, npages,
> - DMA_FROM_DEVICE, &mdetails);
> + err = drm_pagemap_migrate_map_system_pages(dev, pagemap_addr,
> + migrate.dst, npages,
> + DMA_FROM_DEVICE);
> if (err)
> goto err_finalize;
>
> --
> 2.34.1
>
next prev parent reply other threads:[~2026-04-02 14:12 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-19 20:10 [PATCH v5 0/5] Use new dma-map IOVA alloc, link, and sync API in GPU SVM and DRM pagemap Matthew Brost
2026-02-19 20:10 ` [PATCH v5 1/5] drm/pagemap: Add helper to access zone_device_data Matthew Brost
2026-02-19 20:10 ` [PATCH v5 2/5] drm/gpusvm: Use dma-map IOVA alloc, link, and sync API in GPU SVM Matthew Brost
2026-02-19 20:10 ` [PATCH v5 3/5] drm/pagemap: Drop source_peer_migrates flag and assume true Matthew Brost
2026-02-19 20:53 ` Matthew Brost
2026-04-02 10:33 ` Francois Dugast
2026-02-19 20:10 ` [PATCH v5 4/5] drm/pagemap: Split drm_pagemap_migrate_map_pages into device / system Matthew Brost
2026-04-02 14:12 ` Francois Dugast [this message]
2026-02-19 20:10 ` [PATCH v5 5/5] drm/pagemap: Use dma-map IOVA alloc, link, and sync API for DRM pagemap Matthew Brost
2026-04-02 15:59 ` Francois Dugast
2026-04-08 16:46 ` Matthew Brost
2026-02-19 20:18 ` ✓ CI.KUnit: success for Use new dma-map IOVA alloc, link, and sync API in GPU SVM and DRM pagemap (rev5) Patchwork
2026-02-20 8:47 ` ✓ Xe.CI.BAT: " Patchwork
2026-02-20 14:26 ` ✗ Xe.CI.FULL: failure " Patchwork
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=ac55MqY8MucJK6_V@fdugast-desk \
--to=francois.dugast@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=himal.prasad.ghimiray@intel.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=jgg@ziepe.ca \
--cc=leonro@nvidia.com \
--cc=matthew.brost@intel.com \
--cc=thomas.hellstrom@linux.intel.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.