forked from Minki/linux
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: Maarten Lankhorst <maarten.lankhorst@canonical.com>
This commit is contained in:
parent
e3be4c230d
commit
15a996bbb6
|
@ -100,6 +100,18 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
|
||||||
spin_unlock_irq(&fctx->lock);
|
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
|
static void
|
||||||
nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx)
|
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)
|
nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx)
|
||||||
{
|
{
|
||||||
struct nouveau_fence_priv *priv = (void*)chan->drm->fence;
|
struct nouveau_fence_priv *priv = (void*)chan->drm->fence;
|
||||||
|
struct nouveau_cli *cli = (void *)nvif_client(chan->object);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&fctx->flip);
|
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);
|
spin_lock_init(&fctx->lock);
|
||||||
fctx->context = priv->context_base + chan->chid;
|
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)
|
if (!priv->uevent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -230,6 +251,7 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan)
|
||||||
else
|
else
|
||||||
fence_init(&fence->base, &nouveau_fence_ops_legacy,
|
fence_init(&fence->base, &nouveau_fence_ops_legacy,
|
||||||
&fctx->lock, fctx->context, ++fctx->sequence);
|
&fctx->lock, fctx->context, ++fctx->sequence);
|
||||||
|
kref_get(&fctx->fence_ref);
|
||||||
|
|
||||||
trace_fence_emit(&fence->base);
|
trace_fence_emit(&fence->base);
|
||||||
ret = fctx->emit(fence);
|
ret = fctx->emit(fence);
|
||||||
|
@ -480,13 +502,22 @@ static bool nouveau_fence_no_signaling(struct fence *f)
|
||||||
return true;
|
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 = {
|
static const struct fence_ops nouveau_fence_ops_legacy = {
|
||||||
.get_driver_name = nouveau_fence_get_get_driver_name,
|
.get_driver_name = nouveau_fence_get_get_driver_name,
|
||||||
.get_timeline_name = nouveau_fence_get_timeline_name,
|
.get_timeline_name = nouveau_fence_get_timeline_name,
|
||||||
.enable_signaling = nouveau_fence_no_signaling,
|
.enable_signaling = nouveau_fence_no_signaling,
|
||||||
.signaled = nouveau_fence_is_signaled,
|
.signaled = nouveau_fence_is_signaled,
|
||||||
.wait = nouveau_fence_wait_legacy,
|
.wait = nouveau_fence_wait_legacy,
|
||||||
.release = NULL
|
.release = nouveau_fence_release
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool nouveau_fence_enable_signaling(struct fence *f)
|
static bool nouveau_fence_enable_signaling(struct fence *f)
|
||||||
|
|
|
@ -30,6 +30,8 @@ int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool excl
|
||||||
|
|
||||||
struct nouveau_fence_chan {
|
struct nouveau_fence_chan {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
struct kref fence_ref;
|
||||||
|
|
||||||
struct list_head pending;
|
struct list_head pending;
|
||||||
struct list_head flip;
|
struct list_head flip;
|
||||||
|
|
||||||
|
@ -42,7 +44,7 @@ struct nouveau_fence_chan {
|
||||||
|
|
||||||
u32 sequence;
|
u32 sequence;
|
||||||
u32 context;
|
u32 context;
|
||||||
char name[24];
|
char name[32];
|
||||||
|
|
||||||
struct nvif_notify notify;
|
struct nvif_notify notify;
|
||||||
int notify_ref;
|
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_new(struct nouveau_channel *, struct nouveau_fence_chan *);
|
||||||
void nouveau_fence_context_del(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_create(struct nouveau_drm *);
|
||||||
int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32);
|
int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32);
|
||||||
|
|
|
@ -67,7 +67,7 @@ nv04_fence_context_del(struct nouveau_channel *chan)
|
||||||
struct nv04_fence_chan *fctx = chan->fence;
|
struct nv04_fence_chan *fctx = chan->fence;
|
||||||
nouveau_fence_context_del(&fctx->base);
|
nouveau_fence_context_del(&fctx->base);
|
||||||
chan->fence = NULL;
|
chan->fence = NULL;
|
||||||
kfree(fctx);
|
nouveau_fence_context_free(&fctx->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -63,7 +63,7 @@ nv10_fence_context_del(struct nouveau_channel *chan)
|
||||||
nvif_object_fini(&fctx->head[i]);
|
nvif_object_fini(&fctx->head[i]);
|
||||||
nvif_object_fini(&fctx->sema);
|
nvif_object_fini(&fctx->sema);
|
||||||
chan->fence = NULL;
|
chan->fence = NULL;
|
||||||
kfree(fctx);
|
nouveau_fence_context_free(&fctx->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -125,7 +125,7 @@ nv84_fence_context_del(struct nouveau_channel *chan)
|
||||||
nouveau_bo_vma_del(priv->bo, &fctx->vma);
|
nouveau_bo_vma_del(priv->bo, &fctx->vma);
|
||||||
nouveau_fence_context_del(&fctx->base);
|
nouveau_fence_context_del(&fctx->base);
|
||||||
chan->fence = NULL;
|
chan->fence = NULL;
|
||||||
kfree(fctx);
|
nouveau_fence_context_free(&fctx->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue
Block a user