aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-09-29 04:06:18 -0400
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-09-30 08:04:00 -0400
commit15a996bbb6978ae21c497aeadfe20deca6ddd07a (patch)
tree208bcce51bf6bfa6b1d831a15ced5a32a0c9e5b0 /drivers/gpu/drm/nouveau
parente3be4c230dfadf79567a245505a47a90db97f968 (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.c33
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h5
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv10_fence.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv84_fence.c2
5 files changed, 39 insertions, 5 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c
index dfd0b9ed4195..dba1f7e15cb6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -101,6 +101,18 @@ nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
101} 101}
102 102
103static void 103static void
104nouveau_fence_context_put(struct kref *fence_ref)
105{
106 kfree(container_of(fence_ref, struct nouveau_fence_chan, fence_ref));
107}
108
109void
110nouveau_fence_context_free(struct nouveau_fence_chan *fctx)
111{
112 kref_put(&fctx->fence_ref, nouveau_fence_context_put);
113}
114
115static void
104nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) 116nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx)
105{ 117{
106 struct nouveau_fence *fence; 118 struct nouveau_fence *fence;
@@ -141,6 +153,7 @@ void
141nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) 153nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx)
142{ 154{
143 struct nouveau_fence_priv *priv = (void*)chan->drm->fence; 155 struct nouveau_fence_priv *priv = (void*)chan->drm->fence;
156 struct nouveau_cli *cli = (void *)nvif_client(chan->object);
144 int ret; 157 int ret;
145 158
146 INIT_LIST_HEAD(&fctx->flip); 159 INIT_LIST_HEAD(&fctx->flip);
@@ -148,6 +161,14 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
148 spin_lock_init(&fctx->lock); 161 spin_lock_init(&fctx->lock);
149 fctx->context = priv->context_base + chan->chid; 162 fctx->context = priv->context_base + chan->chid;
150 163
164 if (chan == chan->drm->cechan)
165 strcpy(fctx->name, "copy engine channel");
166 else if (chan == chan->drm->channel)
167 strcpy(fctx->name, "generic kernel channel");
168 else
169 strcpy(fctx->name, nvkm_client(&cli->base)->name);
170
171 kref_init(&fctx->fence_ref);
151 if (!priv->uevent) 172 if (!priv->uevent)
152 return; 173 return;
153 174
@@ -230,6 +251,7 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan)
230 else 251 else
231 fence_init(&fence->base, &nouveau_fence_ops_legacy, 252 fence_init(&fence->base, &nouveau_fence_ops_legacy,
232 &fctx->lock, fctx->context, ++fctx->sequence); 253 &fctx->lock, fctx->context, ++fctx->sequence);
254 kref_get(&fctx->fence_ref);
233 255
234 trace_fence_emit(&fence->base); 256 trace_fence_emit(&fence->base);
235 ret = fctx->emit(fence); 257 ret = fctx->emit(fence);
@@ -480,13 +502,22 @@ static bool nouveau_fence_no_signaling(struct fence *f)
480 return true; 502 return true;
481} 503}
482 504
505static void nouveau_fence_release(struct fence *f)
506{
507 struct nouveau_fence *fence = from_fence(f);
508 struct nouveau_fence_chan *fctx = nouveau_fctx(fence);
509
510 kref_put(&fctx->fence_ref, nouveau_fence_context_put);
511 fence_free(&fence->base);
512}
513
483static const struct fence_ops nouveau_fence_ops_legacy = { 514static const struct fence_ops nouveau_fence_ops_legacy = {
484 .get_driver_name = nouveau_fence_get_get_driver_name, 515 .get_driver_name = nouveau_fence_get_get_driver_name,
485 .get_timeline_name = nouveau_fence_get_timeline_name, 516 .get_timeline_name = nouveau_fence_get_timeline_name,
486 .enable_signaling = nouveau_fence_no_signaling, 517 .enable_signaling = nouveau_fence_no_signaling,
487 .signaled = nouveau_fence_is_signaled, 518 .signaled = nouveau_fence_is_signaled,
488 .wait = nouveau_fence_wait_legacy, 519 .wait = nouveau_fence_wait_legacy,
489 .release = NULL 520 .release = nouveau_fence_release
490}; 521};
491 522
492static bool nouveau_fence_enable_signaling(struct fence *f) 523static bool nouveau_fence_enable_signaling(struct fence *f)
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
index a7dc5375c320..943b0b17b1fc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -30,6 +30,8 @@ int nouveau_fence_sync(struct nouveau_bo *, struct nouveau_channel *, bool excl
30 30
31struct nouveau_fence_chan { 31struct nouveau_fence_chan {
32 spinlock_t lock; 32 spinlock_t lock;
33 struct kref fence_ref;
34
33 struct list_head pending; 35 struct list_head pending;
34 struct list_head flip; 36 struct list_head flip;
35 37
@@ -42,7 +44,7 @@ struct nouveau_fence_chan {
42 44
43 u32 sequence; 45 u32 sequence;
44 u32 context; 46 u32 context;
45 char name[24]; 47 char name[32];
46 48
47 struct nvif_notify notify; 49 struct nvif_notify notify;
48 int notify_ref; 50 int notify_ref;
@@ -63,6 +65,7 @@ struct nouveau_fence_priv {
63 65
64void nouveau_fence_context_new(struct nouveau_channel *, struct nouveau_fence_chan *); 66void nouveau_fence_context_new(struct nouveau_channel *, struct nouveau_fence_chan *);
65void nouveau_fence_context_del(struct nouveau_fence_chan *); 67void nouveau_fence_context_del(struct nouveau_fence_chan *);
68void nouveau_fence_context_free(struct nouveau_fence_chan *);
66 69
67int nv04_fence_create(struct nouveau_drm *); 70int nv04_fence_create(struct nouveau_drm *);
68int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32); 71int nv04_fence_mthd(struct nouveau_channel *, u32, u32, u32);
diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c
index 4484131d826a..f9859deb108a 100644
--- a/drivers/gpu/drm/nouveau/nv04_fence.c
+++ b/drivers/gpu/drm/nouveau/nv04_fence.c
@@ -67,7 +67,7 @@ nv04_fence_context_del(struct nouveau_channel *chan)
67 struct nv04_fence_chan *fctx = chan->fence; 67 struct nv04_fence_chan *fctx = chan->fence;
68 nouveau_fence_context_del(&fctx->base); 68 nouveau_fence_context_del(&fctx->base);
69 chan->fence = NULL; 69 chan->fence = NULL;
70 kfree(fctx); 70 nouveau_fence_context_free(&fctx->base);
71} 71}
72 72
73static int 73static int
diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c
index 737d066ffc60..5e1ea1cdce75 100644
--- a/drivers/gpu/drm/nouveau/nv10_fence.c
+++ b/drivers/gpu/drm/nouveau/nv10_fence.c
@@ -63,7 +63,7 @@ nv10_fence_context_del(struct nouveau_channel *chan)
63 nvif_object_fini(&fctx->head[i]); 63 nvif_object_fini(&fctx->head[i]);
64 nvif_object_fini(&fctx->sema); 64 nvif_object_fini(&fctx->sema);
65 chan->fence = NULL; 65 chan->fence = NULL;
66 kfree(fctx); 66 nouveau_fence_context_free(&fctx->base);
67} 67}
68 68
69int 69int
diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c
index 1e5017f905db..41cd1a28d89f 100644
--- a/drivers/gpu/drm/nouveau/nv84_fence.c
+++ b/drivers/gpu/drm/nouveau/nv84_fence.c
@@ -125,7 +125,7 @@ nv84_fence_context_del(struct nouveau_channel *chan)
125 nouveau_bo_vma_del(priv->bo, &fctx->vma); 125 nouveau_bo_vma_del(priv->bo, &fctx->vma);
126 nouveau_fence_context_del(&fctx->base); 126 nouveau_fence_context_del(&fctx->base);
127 chan->fence = NULL; 127 chan->fence = NULL;
128 kfree(fctx); 128 nouveau_fence_context_free(&fctx->base);
129} 129}
130 130
131int 131int