Blob Blame History Raw
From: Ben Skeggs <bskeggs@redhat.com>
Date: Wed, 1 Nov 2017 03:56:19 +1000
Subject: drm/nouveau/imem/nv50: move slow-path locking into rd/wr functions
Git-commit: af515ec8d3fbd8376513eee9648a52d5ab92bbac
Patch-mainline: v4.15-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

This is to simplify upcoming changes.  The slow-path is something that
currently occurs during bootstrap of the BAR2 VMM, while backing up an
object during suspend/resume, or when BAR2 address space runs out.

The latter is a real problem that can happen at runtime, and occurs in
Fedora 26 already (due to some change that causes a lot of channels to
be created at login), so ideally we'd prefer not to make it any slower.

We'd also like suspend/resume speed to not suffer.

Upcoming commits will solve those problems in a better way, making the
extra overhead of moving the locking here a non-issue.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c |   14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -31,8 +31,6 @@
 
 struct nv50_instmem {
 	struct nvkm_instmem base;
-	unsigned long lock_flags;
-	spinlock_t lock;
 	u64 addr;
 };
 
@@ -57,12 +55,15 @@ nv50_instobj_wr32_slow(struct nvkm_memor
 	struct nvkm_device *device = imem->base.subdev.device;
 	u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
+	unsigned long flags;
 
+	spin_lock_irqsave(&imem->base.lock, flags);
 	if (unlikely(imem->addr != base)) {
 		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
 	nvkm_wr32(device, 0x700000 + addr, data);
+	spin_unlock_irqrestore(&imem->base.lock, flags);
 }
 
 static u32
@@ -74,12 +75,15 @@ nv50_instobj_rd32_slow(struct nvkm_memor
 	u64 base = (iobj->mem->offset + offset) & 0xffffff00000ULL;
 	u64 addr = (iobj->mem->offset + offset) & 0x000000fffffULL;
 	u32 data;
+	unsigned long flags;
 
+	spin_lock_irqsave(&imem->base.lock, flags);
 	if (unlikely(imem->addr != base)) {
 		nvkm_wr32(device, 0x001700, base >> 16);
 		imem->addr = base;
 	}
 	data = nvkm_rd32(device, 0x700000 + addr);
+	spin_unlock_irqrestore(&imem->base.lock, flags);
 	return data;
 }
 
@@ -127,8 +131,6 @@ nv50_instobj_map(struct nvkm_memory *mem
 static void
 nv50_instobj_release(struct nvkm_memory *memory)
 {
-	struct nv50_instmem *imem = nv50_instobj(memory)->imem;
-	spin_unlock_irqrestore(&imem->lock, imem->lock_flags);
 }
 
 static void __iomem *
@@ -137,15 +139,12 @@ nv50_instobj_acquire(struct nvkm_memory
 	struct nv50_instobj *iobj = nv50_instobj(memory);
 	struct nv50_instmem *imem = iobj->imem;
 	struct nvkm_vm *vm;
-	unsigned long flags;
 
 	if (!iobj->map && (vm = nvkm_bar_bar2_vmm(imem->base.subdev.device)))
 		nv50_instobj_kmap(iobj, vm);
 	if (!IS_ERR_OR_NULL(iobj->map))
 		return iobj->map;
 
-	spin_lock_irqsave(&imem->lock, flags);
-	imem->lock_flags = flags;
 	return NULL;
 }
 
@@ -254,7 +253,6 @@ nv50_instmem_new(struct nvkm_device *dev
 	if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
 		return -ENOMEM;
 	nvkm_instmem_ctor(&nv50_instmem, device, index, &imem->base);
-	spin_lock_init(&imem->lock);
 	*pimem = &imem->base;
 	return 0;
 }