Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/msm: Fix hw_fence error path cleanup

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 <robdclark@chromium.org>
Patchwork: https://patchwork.freedesktop.org/patch/547088/

+19 -1
+6
drivers/gpu/drm/msm/msm_fence.c
··· 191 191 192 192 f->fctx = fctx; 193 193 194 + /* 195 + * Until this point, the fence was just some pre-allocated memory, 196 + * no-one should have taken a reference to it yet. 197 + */ 198 + WARN_ON(kref_read(&fence->refcount)); 199 + 194 200 dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock, 195 201 fctx->context, ++fctx->last_fence); 196 202 }
+13 -1
drivers/gpu/drm/msm/msm_gem_submit.c
··· 86 86 } 87 87 88 88 dma_fence_put(submit->user_fence); 89 - dma_fence_put(submit->hw_fence); 89 + 90 + /* 91 + * If the submit is freed before msm_job_run(), then hw_fence is 92 + * just some pre-allocated memory, not a reference counted fence. 93 + * Once the job runs and the hw_fence is initialized, it will 94 + * have a refcount of at least one, since the submit holds a ref 95 + * to the hw_fence. 96 + */ 97 + if (kref_read(&submit->hw_fence->refcount) == 0) { 98 + kfree(submit->hw_fence); 99 + } else { 100 + dma_fence_put(submit->hw_fence); 101 + } 90 102 91 103 put_pid(submit->pid); 92 104 msm_submitqueue_put(submit->queue);