drm/nouveau: signal pending fences when channel has been killed
authorBen Skeggs <bskeggs@redhat.com>
Thu, 23 Jan 2020 05:39:27 +0000 (15:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 29 Jan 2020 05:49:47 +0000 (15:49 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_fence.h

index 282fd90b65e134373525fb086c9505878c0d1c25..d9381a0531693d779fd1df592c442fa11acd65d3 100644 (file)
@@ -55,6 +55,8 @@ nouveau_channel_killed(struct nvif_notify *ntfy)
        struct nouveau_cli *cli = (void *)chan->user.client;
        NV_PRINTK(warn, cli, "channel %d killed!\n", chan->chid);
        atomic_set(&chan->killed, 1);
+       if (chan->fence)
+               nouveau_fence_context_kill(chan->fence, -ENODEV);
        return NVIF_NOTIFY_DROP;
 }
 
index 70bb6bb97af87182ce25728b43ac305dc6d8ed51..666f2090d92b269b5826d5a5256873cd32620ed1 100644 (file)
@@ -87,7 +87,7 @@ nouveau_local_fence(struct dma_fence *fence, struct nouveau_drm *drm)
 }
 
 void
-nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
+nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
 {
        struct nouveau_fence *fence;
 
@@ -95,11 +95,19 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
        while (!list_empty(&fctx->pending)) {
                fence = list_entry(fctx->pending.next, typeof(*fence), head);
 
+               if (error)
+                       dma_fence_set_error(&fence->base, error);
+
                if (nouveau_fence_signal(fence))
                        nvif_notify_put(&fctx->notify);
        }
        spin_unlock_irq(&fctx->lock);
+}
 
+void
+nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
+{
+       nouveau_fence_context_kill(fctx, 0);
        nvif_notify_fini(&fctx->notify);
        fctx->dead = 1;
 
index c9e24baaaa4f9b9bb39cbb18c82e9fd15e23ca80..4887caa69c6577256a188e34450690c5a759686d 100644 (file)
@@ -63,6 +63,7 @@ struct nouveau_fence_priv {
 void nouveau_fence_context_new(struct nouveau_channel *, struct nouveau_fence_chan *);
 void nouveau_fence_context_del(struct nouveau_fence_chan *);
 void nouveau_fence_context_free(struct nouveau_fence_chan *);
+void nouveau_fence_context_kill(struct nouveau_fence_chan *, int error);
 
 int nv04_fence_create(struct nouveau_drm *);
 int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32);