]> git.infradead.org Git - nvme.git/commitdiff
Revert "nouveau: push event block/allowing out of the fence context"
authorDave Airlie <airlied@redhat.com>
Fri, 26 Jan 2024 18:04:34 +0000 (04:04 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 26 Jan 2024 18:04:34 +0000 (04:04 +1000)
This reverts commit eacabb5462717a52fccbbbba458365a4f5e61f35.

This commit causes some regressions in desktop usage, this will
reintroduce the original deadlock in DRI_PRIME situations, I've
got an idea to fix it by offloading to a workqueue in a different
spot, however this code has a race condition where we sometimes
miss interrupts so I'd like to fix that as well.

Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_fence.h

index 5057d976fa578cebe2e9e847c6e78634d2b08968..ca762ea5541361bb023e8b0288470502797f1a15 100644 (file)
@@ -62,7 +62,7 @@ nouveau_fence_signal(struct nouveau_fence *fence)
        if (test_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags)) {
                struct nouveau_fence_chan *fctx = nouveau_fctx(fence);
 
-               if (atomic_dec_and_test(&fctx->notify_ref))
+               if (!--fctx->notify_ref)
                        drop = 1;
        }
 
@@ -103,7 +103,6 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
 void
 nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
 {
-       cancel_work_sync(&fctx->allow_block_work);
        nouveau_fence_context_kill(fctx, 0);
        nvif_event_dtor(&fctx->event);
        fctx->dead = 1;
@@ -168,18 +167,6 @@ nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc
        return ret;
 }
 
-static void
-nouveau_fence_work_allow_block(struct work_struct *work)
-{
-       struct nouveau_fence_chan *fctx = container_of(work, struct nouveau_fence_chan,
-                                                      allow_block_work);
-
-       if (atomic_read(&fctx->notify_ref) == 0)
-               nvif_event_block(&fctx->event);
-       else
-               nvif_event_allow(&fctx->event);
-}
-
 void
 nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx)
 {
@@ -191,7 +178,6 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
        } args;
        int ret;
 
-       INIT_WORK(&fctx->allow_block_work, nouveau_fence_work_allow_block);
        INIT_LIST_HEAD(&fctx->flip);
        INIT_LIST_HEAD(&fctx->pending);
        spin_lock_init(&fctx->lock);
@@ -535,19 +521,15 @@ static bool nouveau_fence_enable_signaling(struct dma_fence *f)
        struct nouveau_fence *fence = from_fence(f);
        struct nouveau_fence_chan *fctx = nouveau_fctx(fence);
        bool ret;
-       bool do_work;
 
-       if (atomic_inc_return(&fctx->notify_ref) == 0)
-               do_work = true;
+       if (!fctx->notify_ref++)
+               nvif_event_allow(&fctx->event);
 
        ret = nouveau_fence_no_signaling(f);
        if (ret)
                set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags);
-       else if (atomic_dec_and_test(&fctx->notify_ref))
-               do_work = true;
-
-       if (do_work)
-               schedule_work(&fctx->allow_block_work);
+       else if (!--fctx->notify_ref)
+               nvif_event_block(&fctx->event);
 
        return ret;
 }
index 28f5cf013b8983240204d028c8367249a63912e0..64d33ae7f35610fe763cd34f717335ab7b24ea4e 100644 (file)
@@ -3,7 +3,6 @@
 #define __NOUVEAU_FENCE_H__
 
 #include <linux/dma-fence.h>
-#include <linux/workqueue.h>
 #include <nvif/event.h>
 
 struct nouveau_drm;
@@ -46,9 +45,7 @@ struct nouveau_fence_chan {
        char name[32];
 
        struct nvif_event event;
-       struct work_struct allow_block_work;
-       atomic_t notify_ref;
-       int dead, killed;
+       int notify_ref, dead, killed;
 };
 
 struct nouveau_fence_priv {