drm/gpuvm: Let drm_gpuvm_bo_put() report when the vm_bo object is destroyed
authorBoris Brezillon <boris.brezillon@collabora.com>
Mon, 4 Dec 2023 15:14:06 +0000 (16:14 +0100)
committerBoris Brezillon <boris.brezillon@collabora.com>
Tue, 5 Dec 2023 10:43:57 +0000 (11:43 +0100)
Some users need to release resources attached to the vm_bo object when
it's destroyed. In Panthor's case, we need to release the pin ref so
BO pages can be returned to the system when all GPU mappings are gone.

This could be done through a custom drm_gpuvm::vm_bo_free() hook, but
this has all sort of locking implications that would force us to expose
a drm_gem_shmem_unpin_locked() helper, not to mention the fact that
having a ::vm_bo_free() implementation without a ::vm_bo_alloc() one
seems odd. So let's keep things simple, and extend drm_gpuvm_bo_put()
to report when the object is destroyed.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Danilo Krummrich <dakr@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231204151406.1977285-1-boris.brezillon@collabora.com
drivers/gpu/drm/drm_gpuvm.c
include/drm/drm_gpuvm.h

index 07a6676bc4f9be47c3e7c0a00104070e02286bce..9c0922c1a5a27ccb52e13308e1ef0913c4b83cb9 100644 (file)
@@ -1535,14 +1535,18 @@ drm_gpuvm_bo_destroy(struct kref *kref)
  * hold the dma-resv or driver specific GEM gpuva lock.
  *
  * This function may only be called from non-atomic context.
+ *
+ * Returns: true if vm_bo was destroyed, false otherwise.
  */
-void
+bool
 drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo)
 {
        might_sleep();
 
        if (vm_bo)
-               kref_put(&vm_bo->kref, drm_gpuvm_bo_destroy);
+               return !!kref_put(&vm_bo->kref, drm_gpuvm_bo_destroy);
+
+       return false;
 }
 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put);
 
index b3f82ec7fb17df607b07835cdc9a49e749a2fb4c..6258849382e165e01eacb2568d9b441fd31c5297 100644 (file)
@@ -721,7 +721,7 @@ drm_gpuvm_bo_get(struct drm_gpuvm_bo *vm_bo)
        return vm_bo;
 }
 
-void drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo);
+bool drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo);
 
 struct drm_gpuvm_bo *
 drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,