]> Git Repo - linux.git/commitdiff
drm/msm: Fix hw_fence error path cleanup
authorRob Clark <[email protected]>
Wed, 12 Jul 2023 22:25:23 +0000 (15:25 -0700)
committerRob Clark <[email protected]>
Mon, 17 Jul 2023 19:54:20 +0000 (12:54 -0700)
In an error path where the submit is free'd without the job being run,
the hw_fence pointer is simply a kzalloc'd block of memory.  In this
case we should just kfree() it, rather than trying to decrement it's
reference count.  Fortunately we can tell that this is the case by
checking for a zero refcount, since if the job was run, the submit would
be holding a reference to the hw_fence.

Fixes: f94e6a51e17c ("drm/msm: Pre-allocate hw_fence")
Signed-off-by: Rob Clark <[email protected]>
Patchwork: https://patchwork.freedesktop.org/patch/547088/

drivers/gpu/drm/msm/msm_fence.c
drivers/gpu/drm/msm/msm_gem_submit.c

index 96599ec3eb783d92b263076be8c039b9e576a449..1a5d4f1c8b422bf2406ede6e87d6aef58b7efb19 100644 (file)
@@ -191,6 +191,12 @@ msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx)
 
        f->fctx = fctx;
 
+       /*
+        * Until this point, the fence was just some pre-allocated memory,
+        * no-one should have taken a reference to it yet.
+        */
+       WARN_ON(kref_read(&fence->refcount));
+
        dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock,
                       fctx->context, ++fctx->last_fence);
 }
index 3f1aa4de3b87302aaa1f48f999b37ef8d336454a..9d66498cdc04a606657b19fc8caf0edaea191c94 100644 (file)
@@ -86,7 +86,19 @@ void __msm_gem_submit_destroy(struct kref *kref)
        }
 
        dma_fence_put(submit->user_fence);
-       dma_fence_put(submit->hw_fence);
+
+       /*
+        * If the submit is freed before msm_job_run(), then hw_fence is
+        * just some pre-allocated memory, not a reference counted fence.
+        * Once the job runs and the hw_fence is initialized, it will
+        * have a refcount of at least one, since the submit holds a ref
+        * to the hw_fence.
+        */
+       if (kref_read(&submit->hw_fence->refcount) == 0) {
+               kfree(submit->hw_fence);
+       } else {
+               dma_fence_put(submit->hw_fence);
+       }
 
        put_pid(submit->pid);
        msm_submitqueue_put(submit->queue);
This page took 0.059148 seconds and 4 git commands to generate.