Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15a996bb authored by Maarten Lankhorst's avatar Maarten Lankhorst
Browse files

drm/nouveau: assign fence_chan->name correctly



Make nouveau_fence_chan refcounted, to make trace_fence_destroy
always return the correct name without a race condition.

Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@canonical.com>
parent e3be4c23
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -100,6 +100,18 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
	spin_unlock_irq(&fctx->lock);
}

static void
nouveau_fence_context_put(struct kref *fence_ref)
{
	kfree(container_of(fence_ref, struct nouveau_fence_chan, fence_ref));
}

void
nouveau_fence_context_free(struct nouveau_fence_chan *fctx)
{
	kref_put(&fctx->fence_ref, nouveau_fence_context_put);
}

static void
nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx)
{
@@ -141,6 +153,7 @@ void
nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx)
{
	struct nouveau_fence_priv *priv = (void*)chan->drm->fence;
	struct nouveau_cli *cli = (void *)nvif_client(chan->object);
	int ret;

	INIT_LIST_HEAD(&fctx->flip);
@@ -148,6 +161,14 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
	spin_lock_init(&fctx->lock);
	fctx->context = priv->context_base + chan->chid;

	if (chan == chan->drm->cechan)
		strcpy(fctx->name, "copy engine channel");
	else if (chan == chan->drm->channel)
		strcpy(fctx->name, "generic kernel channel");
	else
		strcpy(fctx->name, nvkm_client(&cli->base)->name);

	kref_init(&fctx->fence_ref);
	if (!priv->uevent)
		return;

@@ -230,6 +251,7 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan)
	else
		fence_init(&fence->base, &nouveau_fence_ops_legacy,
			   &fctx->lock, fctx->context, ++fctx->sequence);
	kref_get(&fctx->fence_ref);

	trace_fence_emit(&fence->base);
	ret = fctx->emit(fence);
@@ -480,13 +502,22 @@ static bool nouveau_fence_no_signaling(struct fence *f)
	return true;
}

static void nouveau_fence_release(struct fence *f)
{
	struct nouveau_fence *fence = from_fence(f);
	struct nouveau_fence_chan *fctx = nouveau_fctx(fence);

	kref_put(&fctx->fence_ref, nouveau_fence_context_put);
	fence_free(&fence->base);
}

static const struct fence_ops nouveau_fence_ops_legacy = {
	.get_driver_name = nouveau_fence_get_get_driver_name,
	.get_timeline_name = nouveau_fence_get_timeline_name,
	.enable_signaling = nouveau_fence_no_signaling,
	.signaled = nouveau_fence_is_signaled,
	.wait = nouveau_fence_wait_legacy,
	.release = NULL
	.release = nouveau_fence_release
};

static bool nouveau_fence_enable_signaling(struct fence *f)
+4 −1
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool excl

struct nouveau_fence_chan {
	spinlock_t lock;
	struct kref fence_ref;

	struct list_head pending;
	struct list_head flip;

@@ -42,7 +44,7 @@ struct nouveau_fence_chan {

	u32 sequence;
	u32 context;
	char name[24];
	char name[32];

	struct nvif_notify notify;
	int notify_ref;
@@ -63,6 +65,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 *);

int nv04_fence_create(struct nouveau_drm *);
int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32);
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ nv04_fence_context_del(struct nouveau_channel *chan)
	struct nv04_fence_chan *fctx = chan->fence;
	nouveau_fence_context_del(&fctx->base);
	chan->fence = NULL;
	kfree(fctx);
	nouveau_fence_context_free(&fctx->base);
}

static int
+1 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ nv10_fence_context_del(struct nouveau_channel *chan)
		nvif_object_fini(&fctx->head[i]);
	nvif_object_fini(&fctx->sema);
	chan->fence = NULL;
	kfree(fctx);
	nouveau_fence_context_free(&fctx->base);
}

int
+1 −1
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ nv84_fence_context_del(struct nouveau_channel *chan)
	nouveau_bo_vma_del(priv->bo, &fctx->vma);
	nouveau_fence_context_del(&fctx->base);
	chan->fence = NULL;
	kfree(fctx);
	nouveau_fence_context_free(&fctx->base);
}

int