diff options
author | Danilo Krummrich <dakr@redhat.com> | 2023-08-04 20:23:48 +0200 |
---|---|---|
committer | Danilo Krummrich <dakr@redhat.com> | 2023-08-04 20:34:37 +0200 |
commit | f124eef76f855d9f3df8827cb1e166f96994042c (patch) | |
tree | b20774843f812b756f9e57a2598a35127fa6f55f /drivers/gpu/drm/nouveau/nouveau_fence.c | |
parent | 7f2a0b50b2b20308a19602b51c647566c62e144c (diff) | |
download | lwn-f124eef76f855d9f3df8827cb1e166f96994042c.tar.gz lwn-f124eef76f855d9f3df8827cb1e166f96994042c.zip |
drm/nouveau: fence: fail to emit when fence context is killed
The new VM_BIND UAPI implementation introduced in subsequent commits
will allow asynchronous jobs processing push buffers and emitting
fences.
If a fence context is killed, e.g. due to a channel fault, jobs which
are already queued for execution might still emit new fences. In such a
case a job would hang forever.
To fix that, fail to emit a new fence on a killed fence context with
-ENODEV to unblock the job.
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Danilo Krummrich <dakr@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230804182406.5222-9-dakr@redhat.com
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_fence.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fence.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index e946408f945b..77c739a55b19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -96,6 +96,7 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error) if (nouveau_fence_signal(fence)) nvif_event_block(&fctx->event); } + fctx->killed = 1; spin_unlock_irqrestore(&fctx->lock, flags); } @@ -229,6 +230,12 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) dma_fence_get(&fence->base); spin_lock_irq(&fctx->lock); + if (unlikely(fctx->killed)) { + spin_unlock_irq(&fctx->lock); + dma_fence_put(&fence->base); + return -ENODEV; + } + if (nouveau_fence_update(chan, fctx)) nvif_event_block(&fctx->event); |