summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2016-12-14 09:52:39 +1000
committerBen Skeggs <bskeggs@redhat.com>2017-01-31 19:51:00 +1000
commit9b913fade82627755f5df8a7708f88b8f8c50e4e (patch)
treef97f80b6bcc9ba64bd4c635eca8f3a14a2587e51
parentd4671e9534d5f5c67130c0fa429708e40fe415d4 (diff)
downloadnouveau-9b913fade82627755f5df8a7708f88b8f8c50e4e.tar.gz
fence/g84-: protect against concurrent access to semaphore buffers
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drm/nouveau/nouveau_fence.h1
-rw-r--r--drm/nouveau/nv84_fence.c6
2 files changed, 7 insertions, 0 deletions
diff --git a/drm/nouveau/nouveau_fence.h b/drm/nouveau/nouveau_fence.h
index ccdce1b4e..d5e58a38f 100644
--- a/drm/nouveau/nouveau_fence.h
+++ b/drm/nouveau/nouveau_fence.h
@@ -99,6 +99,7 @@ struct nv84_fence_priv {
struct nouveau_bo *bo;
struct nouveau_bo *bo_gart;
u32 *suspend;
+ struct mutex mutex;
};
int nv84_fence_context_new(struct nouveau_channel *);
diff --git a/drm/nouveau/nv84_fence.c b/drm/nouveau/nv84_fence.c
index 52b87ae83..f0b322bec 100644
--- a/drm/nouveau/nv84_fence.c
+++ b/drm/nouveau/nv84_fence.c
@@ -107,8 +107,10 @@ nv84_fence_context_del(struct nouveau_channel *chan)
struct nv84_fence_chan *fctx = chan->fence;
nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence);
+ mutex_lock(&priv->mutex);
nouveau_bo_vma_del(priv->bo, &fctx->vma_gart);
nouveau_bo_vma_del(priv->bo, &fctx->vma);
+ mutex_unlock(&priv->mutex);
nouveau_fence_context_del(&fctx->base);
chan->fence = NULL;
nouveau_fence_context_free(&fctx->base);
@@ -134,11 +136,13 @@ nv84_fence_context_new(struct nouveau_channel *chan)
fctx->base.sync32 = nv84_fence_sync32;
fctx->base.sequence = nv84_fence_read(chan);
+ mutex_lock(&priv->mutex);
ret = nouveau_bo_vma_add(priv->bo, cli->vm, &fctx->vma);
if (ret == 0) {
ret = nouveau_bo_vma_add(priv->bo_gart, cli->vm,
&fctx->vma_gart);
}
+ mutex_unlock(&priv->mutex);
if (ret)
nv84_fence_context_del(chan);
@@ -212,6 +216,8 @@ nv84_fence_create(struct nouveau_drm *drm)
priv->base.context_base = dma_fence_context_alloc(priv->base.contexts);
priv->base.uevent = true;
+ mutex_init(&priv->mutex);
+
/* Use VRAM if there is any ; otherwise fallback to system memory */
domain = drm->device.info.ram_size != 0 ? TTM_PL_FLAG_VRAM :
/*