Commit 4d7acc8f authored by Dave Airlie's avatar Dave Airlie

Revert "nouveau: push event block/allowing out of the fence context"

This reverts commit eacabb54.

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: default avatarDave Airlie <airlied@redhat.com>
parent 9c4a1126
...@@ -62,7 +62,7 @@ nouveau_fence_signal(struct nouveau_fence *fence) ...@@ -62,7 +62,7 @@ nouveau_fence_signal(struct nouveau_fence *fence)
if (test_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags)) { if (test_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags)) {
struct nouveau_fence_chan *fctx = nouveau_fctx(fence); struct nouveau_fence_chan *fctx = nouveau_fctx(fence);
if (atomic_dec_and_test(&fctx->notify_ref)) if (!--fctx->notify_ref)
drop = 1; drop = 1;
} }
...@@ -103,7 +103,6 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error) ...@@ -103,7 +103,6 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
void void
nouveau_fence_context_del(struct nouveau_fence_chan *fctx) nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
{ {
cancel_work_sync(&fctx->allow_block_work);
nouveau_fence_context_kill(fctx, 0); nouveau_fence_context_kill(fctx, 0);
nvif_event_dtor(&fctx->event); nvif_event_dtor(&fctx->event);
fctx->dead = 1; fctx->dead = 1;
...@@ -168,18 +167,6 @@ nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc ...@@ -168,18 +167,6 @@ nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc
return ret; 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 void
nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) 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 ...@@ -191,7 +178,6 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
} args; } args;
int ret; int ret;
INIT_WORK(&fctx->allow_block_work, nouveau_fence_work_allow_block);
INIT_LIST_HEAD(&fctx->flip); INIT_LIST_HEAD(&fctx->flip);
INIT_LIST_HEAD(&fctx->pending); INIT_LIST_HEAD(&fctx->pending);
spin_lock_init(&fctx->lock); spin_lock_init(&fctx->lock);
...@@ -535,19 +521,15 @@ static bool nouveau_fence_enable_signaling(struct dma_fence *f) ...@@ -535,19 +521,15 @@ static bool nouveau_fence_enable_signaling(struct dma_fence *f)
struct nouveau_fence *fence = from_fence(f); struct nouveau_fence *fence = from_fence(f);
struct nouveau_fence_chan *fctx = nouveau_fctx(fence); struct nouveau_fence_chan *fctx = nouveau_fctx(fence);
bool ret; bool ret;
bool do_work;
if (atomic_inc_return(&fctx->notify_ref) == 0) if (!fctx->notify_ref++)
do_work = true; nvif_event_allow(&fctx->event);
ret = nouveau_fence_no_signaling(f); ret = nouveau_fence_no_signaling(f);
if (ret) if (ret)
set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags); set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags);
else if (atomic_dec_and_test(&fctx->notify_ref)) else if (!--fctx->notify_ref)
do_work = true; nvif_event_block(&fctx->event);
if (do_work)
schedule_work(&fctx->allow_block_work);
return ret; return ret;
} }
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
#define __NOUVEAU_FENCE_H__ #define __NOUVEAU_FENCE_H__
#include <linux/dma-fence.h> #include <linux/dma-fence.h>
#include <linux/workqueue.h>
#include <nvif/event.h> #include <nvif/event.h>
struct nouveau_drm; struct nouveau_drm;
...@@ -46,9 +45,7 @@ struct nouveau_fence_chan { ...@@ -46,9 +45,7 @@ struct nouveau_fence_chan {
char name[32]; char name[32];
struct nvif_event event; struct nvif_event event;
struct work_struct allow_block_work; int notify_ref, dead, killed;
atomic_t notify_ref;
int dead, killed;
}; };
struct nouveau_fence_priv { struct nouveau_fence_priv {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment