On Thu, Jun 18, 2026 at 04:08:59PM +0800, Honglei Huang wrote:
> From: Honglei Huang <[email protected]>
> 
> drm_gpusvm_pages is the layer that actually represents physical
> pages/mappings it owns the dma_addr array, the dma_iova_state...
> With the previous patch, so drm_gpusvm_pages is now strictly about
> physical pages and their DMA view.
> 
> Since now the drm_gpusvm_pages instance is inherently bound to one
> specific drm_device, make that ownership explicit by giving
> drm_gpusvm_pages its own drm_device handle, and drive all DMA through
> it instead of through the gpusvm:
> 
>   - Add drm to struct drm_gpusvm_pages and route all DMA in
>     drm_gpusvm_get_pages() / __drm_gpusvm_unmap_pages() through
>     svm_pages->drm instead of gpusvm->drm.
>   - Bind svm_pages->drm where the pages object is initialised
>     (drm_gpusvm_range_alloc() and the xe userptr setup) and require
>     it to be set on entry to drm_gpusvm_get_pages(); the dma device
>     is immutable for the lifetime of the pages instance. A later
>     patch introduces drm_gpusvm_init_pages() to centralise this.
> 
> Suggested-by: Matthew Brost <[email protected]>

I think both sashiko issues are raised here are valid, but pre-existing
so I don't think it fair to hold up this patch, but these should be
fixed. If you have time, feel free post fixes or I'll circle around to
fixing the issues.

So with that:
Reviewed-by: Matthew Brost <[email protected]>

> Signed-off-by: Honglei Huang <[email protected]>
> ---
>  drivers/gpu/drm/drm_gpusvm.c    | 30 ++++++++++++++++++++----------
>  drivers/gpu/drm/xe/xe_userptr.c |  2 ++
>  include/drm/drm_gpusvm.h        |  2 ++
>  3 files changed, 24 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c
> index df900553f21..155e3c2e703 100644
> --- a/drivers/gpu/drm/drm_gpusvm.c
> +++ b/drivers/gpu/drm/drm_gpusvm.c
> @@ -641,6 +641,7 @@ drm_gpusvm_range_alloc(struct drm_gpusvm *gpusvm,
>       range->itree.last = ALIGN(fault_addr + 1, chunk_size) - 1;
>       INIT_LIST_HEAD(&range->entry);
>       range->pages.notifier_seq = LONG_MAX;
> +     range->pages.drm = gpusvm->drm;
>       range->flags.migrate_devmem = migrate_devmem ? 1 : 0;
>  
>       return range;
> @@ -1135,11 +1136,16 @@ static void __drm_gpusvm_unmap_pages(struct 
> drm_gpusvm *gpusvm,
>                                    unsigned long npages)
>  {
>       struct drm_pagemap *dpagemap = svm_pages->dpagemap;
> -     struct device *dev = gpusvm->drm->dev;
> +     struct device *dev;
>       unsigned long i, j;
>  
>       lockdep_assert_held(&gpusvm->notifier_lock);
>  
> +     if (!svm_pages->drm)
> +             return;
> +
> +     dev = svm_pages->drm->dev;
> +
>       if (svm_pages->flags.has_dma_mapping) {
>               struct drm_gpusvm_pages_flags flags = {
>                       .__flags = svm_pages->flags.__flags,
> @@ -1421,6 +1427,9 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
>                                                          DMA_BIDIRECTIONAL;
>       struct dma_iova_state *state = &svm_pages->state;
>  
> +     if (!svm_pages->drm)
> +             return -EINVAL;
> +
>  retry:
>       if (time_after(jiffies, timeout))
>               return -EBUSY;
> @@ -1520,7 +1529,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
>  
>                               pagemap = page_pgmap(page);
>                               dpagemap = drm_pagemap_page_to_dpagemap(page);
> -                             if (drm_WARN_ON(gpusvm->drm, !dpagemap)) {
> +                             if (drm_WARN_ON(svm_pages->drm, !dpagemap)) {
>                                       /*
>                                        * Raced. This is not supposed to happen
>                                        * since hmm_range_fault() should've 
> migrated
> @@ -1532,10 +1541,10 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
>                       }
>                       svm_pages->dma_addr[j] =
>                               dpagemap->ops->device_map(dpagemap,
> -                                                       gpusvm->drm->dev,
> +                                                       svm_pages->drm->dev,
>                                                         page, order,
>                                                         dma_dir);
> -                     if (dma_mapping_error(gpusvm->drm->dev,
> +                     if (dma_mapping_error(svm_pages->drm->dev,
>                                             svm_pages->dma_addr[j].addr)) {
>                               err = -EFAULT;
>                               goto err_unmap;
> @@ -1555,11 +1564,11 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
>                       }
>  
>                       if (!i)
> -                             dma_iova_try_alloc(gpusvm->drm->dev, state,
> +                             dma_iova_try_alloc(svm_pages->drm->dev, state,
>                                                  0, npages * PAGE_SIZE);
>  
>                       if (dma_use_iova(state)) {
> -                             err = dma_iova_link(gpusvm->drm->dev, state,
> +                             err = dma_iova_link(svm_pages->drm->dev, state,
>                                                   hmm_pfn_to_phys(pfns[i]),
>                                                   svm_pages->state_offset,
>                                                   PAGE_SIZE << order,
> @@ -1570,11 +1579,11 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
>                               addr = state->addr + svm_pages->state_offset;
>                               svm_pages->state_offset += PAGE_SIZE << order;
>                       } else {
> -                             addr = dma_map_page(gpusvm->drm->dev,
> +                             addr = dma_map_page(svm_pages->drm->dev,
>                                                   page, 0,
>                                                   PAGE_SIZE << order,
>                                                   dma_dir);
> -                             if (dma_mapping_error(gpusvm->drm->dev, addr)) {
> +                             if (dma_mapping_error(svm_pages->drm->dev, 
> addr)) {
>                                       err = -EFAULT;
>                                       goto err_unmap;
>                               }
> @@ -1590,7 +1599,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
>       }
>  
>       if (dma_use_iova(state)) {
> -             err = dma_iova_sync(gpusvm->drm->dev, state, 0,
> +             err = dma_iova_sync(svm_pages->drm->dev, state, 0,
>                                   svm_pages->state_offset);
>               if (err)
>                       goto err_unmap;
> @@ -1640,7 +1649,8 @@ int drm_gpusvm_range_get_pages(struct drm_gpusvm 
> *gpusvm,
>                              struct drm_gpusvm_range *range,
>                              const struct drm_gpusvm_ctx *ctx)
>  {
> -     return drm_gpusvm_get_pages(gpusvm, &range->pages, gpusvm->mm,
> +     return drm_gpusvm_get_pages(gpusvm, &range->pages,
> +                                 gpusvm->mm,
>                                   &range->notifier->notifier,
>                                   drm_gpusvm_range_start(range),
>                                   drm_gpusvm_range_end(range), ctx);
> diff --git a/drivers/gpu/drm/xe/xe_userptr.c b/drivers/gpu/drm/xe/xe_userptr.c
> index 6761005c0b9..1b540e62af6 100644
> --- a/drivers/gpu/drm/xe/xe_userptr.c
> +++ b/drivers/gpu/drm/xe/xe_userptr.c
> @@ -390,6 +390,7 @@ int xe_userptr_setup(struct xe_userptr_vma *uvma, 
> unsigned long start,
>                    unsigned long range)
>  {
>       struct xe_userptr *userptr = &uvma->userptr;
> +     struct xe_vm *vm = xe_vma_vm(&uvma->vma);
>       int err;
>  
>       INIT_LIST_HEAD(&userptr->invalidate_link);
> @@ -402,6 +403,7 @@ int xe_userptr_setup(struct xe_userptr_vma *uvma, 
> unsigned long start,
>               return err;
>  
>       userptr->pages.notifier_seq = LONG_MAX;
> +     userptr->pages.drm = &vm->xe->drm;
>  
>       return 0;
>  }
> diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h
> index 251a7266a73..842353afb27 100644
> --- a/include/drm/drm_gpusvm.h
> +++ b/include/drm/drm_gpusvm.h
> @@ -129,6 +129,7 @@ struct drm_gpusvm_pages_flags {
>  /**
>   * struct drm_gpusvm_pages - Structure representing a GPU SVM mapped pages
>   *
> + * @drm: The DRM device that owns the dma mappings
>   * @dma_addr: Device address array
>   * @dpagemap: The struct drm_pagemap of the device pages we're dma-mapping.
>   *            Note this is assuming only one drm_pagemap per range is 
> allowed.
> @@ -138,6 +139,7 @@ struct drm_gpusvm_pages_flags {
>   * @flags: Flags for the range; see &struct drm_gpusvm_pages_flags
>   */
>  struct drm_gpusvm_pages {
> +     struct drm_device *drm;
>       struct drm_pagemap_addr *dma_addr;
>       struct drm_pagemap *dpagemap;
>       struct dma_iova_state state;
> -- 
> 2.34.1
> 

Reply via email to