Although I would not have expected this to happen, we seem to run into
race conditions if instobjs are accessed concurrently. Use a global lock
for safety.

Signed-off-by: Alexandre Courbot <[email protected]>
---
 drm/nouveau/nvkm/subdev/instmem/gk20a.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drm/nouveau/nvkm/subdev/instmem/gk20a.c 
b/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index fc419bb8eab7..d015633b8edd 100644
--- a/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -92,6 +92,7 @@ struct gk20a_instmem {
 
        /* protects vaddr_* and gk20a_instobj::vaddr* */
        spinlock_t lock;
+       unsigned long flags;
 
        /* CPU mappings LRU */
        unsigned int vaddr_use;
@@ -188,12 +189,11 @@ gk20a_instobj_acquire(struct nvkm_memory *memory)
        struct gk20a_instobj *node = gk20a_instobj(memory);
        struct gk20a_instmem *imem = node->imem;
        struct nvkm_ltc *ltc = imem->base.subdev.device->ltc;
-       const u64 size = nvkm_memory_size(memory);
-       unsigned long flags;
+       u64 size;
 
        nvkm_ltc_flush(ltc);
 
-       spin_lock_irqsave(&imem->lock, flags);
+       spin_lock_irqsave(&imem->lock, imem->flags);
 
        if (node->vaddr) {
                /* remove us from the LRU list since we cannot be unmapped */
@@ -202,6 +202,8 @@ gk20a_instobj_acquire(struct nvkm_memory *memory)
                goto out;
        }
 
+       size = nvkm_memory_size(memory);
+
        /* try to free some address space if we reached the limit */
        gk20a_instmem_vaddr_gc(imem, size);
 
@@ -218,8 +220,6 @@ gk20a_instobj_acquire(struct nvkm_memory *memory)
                   imem->vaddr_use, imem->vaddr_max);
 
 out:
-       spin_unlock_irqrestore(&imem->lock, flags);
-
        return node->vaddr;
 }
 
@@ -229,14 +229,11 @@ gk20a_instobj_release(struct nvkm_memory *memory)
        struct gk20a_instobj *node = gk20a_instobj(memory);
        struct gk20a_instmem *imem = node->imem;
        struct nvkm_ltc *ltc = imem->base.subdev.device->ltc;
-       unsigned long flags;
-
-       spin_lock_irqsave(&imem->lock, flags);
 
        /* add ourselves to the LRU list so our CPU mapping can be freed */
        list_add_tail(&node->vaddr_node, &imem->vaddr_lru);
 
-       spin_unlock_irqrestore(&imem->lock, flags);
+       spin_unlock_irqrestore(&imem->lock, imem->flags);
 
        wmb();
        nvkm_ltc_invalidate(ltc);
-- 
2.6.1

_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to