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

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
Loading
Loading
Loading
Loading
+5 −23
Original line number Diff line number Diff line
@@ -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;
}
+1 −4
Original line number Diff line number Diff line
@@ -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 {