From e03078cabd056b32e65fb9e50fcea9ba068cac37 Mon Sep 17 00:00:00 2001 From: Kostadin Atanasov Date: Wed, 13 Nov 2013 19:40:45 +0200 Subject: [PATCH] protect fence channel with spin lock Signed-off-by: Kostadin Atanasov --- drivers/gpu/drm/nouveau/nouveau_fence.c | 11 +++++++++++ drivers/gpu/drm/nouveau/nouveau_fence.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index be31499..9c68d17 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -52,7 +52,9 @@ nouveau_fence_signal(struct nouveau_fence *fence) list_del(&work->head); } + spin_lock(&fence->chlock); fence->channel = NULL; + spin_unlock(&fence->chlock); list_del(&fence->head); } @@ -143,6 +145,7 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) int ret; fence->channel = chan; + spin_lock_init(&fence->chlock); fence->timeout = jiffies + (15 * DRM_HZ); fence->sequence = ++fctx->sequence; @@ -194,6 +197,9 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) nouveau_event_get(pfifo->uevent, 0, &uevent.handler); + /* our caller has the lock but nouveau_fence_done may also want it */ + spin_unlock(&fence->chlock); + if (fence->timeout) { unsigned long timeout = fence->timeout - jiffies; @@ -224,6 +230,9 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) } } + /* restore caller lock state */ + spin_lock(&fence->chlock); + nouveau_event_put(pfifo->uevent, 0, &uevent.handler); if (unlikely(ret < 0)) return ret; @@ -241,7 +250,9 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr) int ret = 0; while (priv && priv->uevent && lazy && !nouveau_fence_done(fence)) { + spin_lock(&fence->chlock); ret = nouveau_fence_wait_uevent(fence, intr); + spin_unlock(&fence->chlock); if (ret < 0) return ret; } diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h index c57bb61..c7d9c00 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.h +++ b/drivers/gpu/drm/nouveau/nouveau_fence.h @@ -11,6 +11,8 @@ struct nouveau_fence { bool sysmem; struct nouveau_channel *channel; + spinlock_t chlock; + unsigned long timeout; u32 sequence; }; -- 1.8.4.2