summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_exec.c
diff options
context:
space:
mode:
authorDanilo Krummrich <dakr@redhat.com>2023-08-30 00:38:02 +0200
committerDanilo Krummrich <dakr@redhat.com>2023-08-31 00:46:23 +0200
commit978474dc8278f661930e02e08d292a45a45fa01a (patch)
tree142d03f066ad67bf867c8e7926452a7fff48db75 /drivers/gpu/drm/nouveau/nouveau_exec.c
parent4b2fd81f2af7147e844ecec0c5c07a16bca6b86e (diff)
drm/nouveau: fence: fix undefined fence state after emit
nouveau_fence_emit() can fail before and after initializing the dma-fence and hence before and after initializing the dma-fence' kref. In order to avoid nouveau_fence_emit() potentially failing before dma-fence initialization pass the channel to nouveau_fence_new() already and perform the required check before even allocating the fence. While at it, restore the original behavior of nouveau_fence_new() and add nouveau_fence_create() for separate (pre-)allocation instead. Always splitting up allocation end emit wasn't a good idea in the first place. Hence, limit it to the places where we actually need to pre-allocate. Fixes: 7f2a0b50b2b2 ("drm/nouveau: fence: separate fence alloc and emit") Signed-off-by: Danilo Krummrich <dakr@redhat.com> Reviewed-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230829223847.4406-1-dakr@redhat.com
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_exec.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_exec.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c b/drivers/gpu/drm/nouveau/nouveau_exec.c
index a90c4cd8cbb2..19024ce21fbb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_exec.c
+++ b/drivers/gpu/drm/nouveau/nouveau_exec.c
@@ -96,7 +96,8 @@ nouveau_exec_job_submit(struct nouveau_job *job)
unsigned long index;
int ret;
- ret = nouveau_fence_new(&exec_job->fence);
+ /* Create a new fence, but do not emit yet. */
+ ret = nouveau_fence_create(&exec_job->fence, exec_job->chan);
if (ret)
return ret;
@@ -170,13 +171,17 @@ nouveau_exec_job_run(struct nouveau_job *job)
nv50_dma_push(chan, p->va, p->va_len, no_prefetch);
}
- ret = nouveau_fence_emit(fence, chan);
+ ret = nouveau_fence_emit(fence);
if (ret) {
+ nouveau_fence_unref(&exec_job->fence);
NV_PRINTK(err, job->cli, "error fencing pushbuf: %d\n", ret);
WIND_RING(chan);
return ERR_PTR(ret);
}
+ /* The fence was emitted successfully, set the job's fence pointer to
+ * NULL in order to avoid freeing it up when the job is cleaned up.
+ */
exec_job->fence = NULL;
return &fence->base;
@@ -189,7 +194,7 @@ nouveau_exec_job_free(struct nouveau_job *job)
nouveau_job_free(job);
- nouveau_fence_unref(&exec_job->fence);
+ kfree(exec_job->fence);
kfree(exec_job->push.s);
kfree(exec_job);
}