Message ID | 20140307111848.GA8637@linutronix.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
* Maarten Lankhorst | 2014-03-07 12:36:13 [+0100]: >>I can't find any kind of locking so my question is what ensures that chan is >>not set to NULL between nouveau_fence_done() and >>nouveau_fence_wait_uevent()? There are just a few opcodes in between but >>nothing that pauses nouveau_fence_signal(). >Absolutely nothing. :-) Worse still, there's no guarantee that channel isn't freed, but hopefully that is less likely to be an issue. Okay, so I hit the correct spot. What do we do here? Do you want the patch I posted without the WARN_ON() or do you prefer to fix this in an other way? >~Maarten Sebastian
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -184,14 +184,20 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) { struct nouveau_channel *chan = fence->channel; - struct nouveau_fifo *pfifo = nouveau_fifo(chan->drm->device); - struct nouveau_fence_priv *priv = chan->drm->fence; + struct nouveau_fifo *pfifo; + struct nouveau_fence_priv *priv; struct nouveau_fence_uevent uevent = { .handler.func = nouveau_fence_wait_uevent_handler, - .priv = priv, }; int ret = 0; + if (WARN_ON_ONCE(!chan)) + return 0; + + pfifo = nouveau_fifo(chan->drm->device); + priv = chan->drm->fence; + uevent.priv = priv; + nouveau_event_get(pfifo->uevent, 0, &uevent.handler); if (fence->timeout) {