On Sat, Oct 25, 2025 at 02:03:59PM +0200, Thomas Hellström wrote:
> To be able to keep track of drm_pagemap usage, add a refcounted
> backpointer to struct drm_pagemap_zdd. This will keep the drm_pagemap
> reference count from dropping to zero as long as there are drm_pagemap
> pages present in a CPU address space.
> 
> Signed-off-by: Thomas Hellström <[email protected]>

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

> ---
>  drivers/gpu/drm/drm_pagemap.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
> index 4b8692f0b2a2..173b3ecb07d5 100644
> --- a/drivers/gpu/drm/drm_pagemap.c
> +++ b/drivers/gpu/drm/drm_pagemap.c
> @@ -62,6 +62,7 @@
>   *
>   * @refcount: Reference count for the zdd
>   * @devmem_allocation: device memory allocation
> + * @dpagemap: Refcounted pointer to the underlying struct drm_pagemap.
>   * @device_private_page_owner: Device private pages owner
>   *
>   * This structure serves as a generic wrapper installed in
> @@ -74,11 +75,13 @@
>  struct drm_pagemap_zdd {
>       struct kref refcount;
>       struct drm_pagemap_devmem *devmem_allocation;
> +     struct drm_pagemap *dpagemap;
>       void *device_private_page_owner;
>  };
>  
>  /**
>   * drm_pagemap_zdd_alloc() - Allocate a zdd structure.
> + * @dpagemap: Pointer to the underlying struct drm_pagemap.
>   * @device_private_page_owner: Device private pages owner
>   *
>   * This function allocates and initializes a new zdd structure. It sets up 
> the
> @@ -87,7 +90,7 @@ struct drm_pagemap_zdd {
>   * Return: Pointer to the allocated zdd on success, ERR_PTR() on failure.
>   */
>  static struct drm_pagemap_zdd *
> -drm_pagemap_zdd_alloc(void *device_private_page_owner)
> +drm_pagemap_zdd_alloc(struct drm_pagemap *dpagemap, void 
> *device_private_page_owner)
>  {
>       struct drm_pagemap_zdd *zdd;
>  
> @@ -98,6 +101,7 @@ drm_pagemap_zdd_alloc(void *device_private_page_owner)
>       kref_init(&zdd->refcount);
>       zdd->devmem_allocation = NULL;
>       zdd->device_private_page_owner = device_private_page_owner;
> +     zdd->dpagemap = drm_pagemap_get(dpagemap);
>  
>       return zdd;
>  }
> @@ -127,6 +131,7 @@ static void drm_pagemap_zdd_destroy(struct kref *ref)
>       struct drm_pagemap_zdd *zdd =
>               container_of(ref, struct drm_pagemap_zdd, refcount);
>       struct drm_pagemap_devmem *devmem = zdd->devmem_allocation;
> +     struct drm_pagemap *dpagemap = zdd->dpagemap;
>  
>       if (devmem) {
>               complete_all(&devmem->detached);
> @@ -134,6 +139,7 @@ static void drm_pagemap_zdd_destroy(struct kref *ref)
>                       devmem->ops->devmem_release(devmem);
>       }
>       kfree(zdd);
> +     drm_pagemap_put(dpagemap);
>  }
>  
>  /**
> @@ -366,7 +372,7 @@ int drm_pagemap_migrate_to_devmem(struct 
> drm_pagemap_devmem *devmem_allocation,
>       pagemap_addr = buf + (2 * sizeof(*migrate.src) * npages);
>       pages = buf + (2 * sizeof(*migrate.src) + sizeof(*pagemap_addr)) * 
> npages;
>  
> -     zdd = drm_pagemap_zdd_alloc(pgmap_owner);
> +     zdd = drm_pagemap_zdd_alloc(devmem_allocation->dpagemap, pgmap_owner);
>       if (!zdd) {
>               err = -ENOMEM;
>               goto err_free;
> -- 
> 2.51.0
> 

Reply via email to