ArchiveOrangemail archive

Nouveau development list


nouveau.lists.freedesktop.org
(List home) (Recent threads) (85 other Freedesktop.org lists)

Subscription Options

  • RSS or Atom: Read-only subscription using a browser or aggregator. This is the recommended way if you don't need to send messages to the list. You can learn more about feed syndication and clients here.
  • Conventional: All messages are delivered to your mail address, and you can reply. To subscribe, send an email to the list's subscribe address with "subscribe" in the subject line, or visit the list's homepage here.
  • Moderate traffic list: up to 30 messages per day
  • This list contains about 12,666 messages, beginning May 2007
  • 4 messages added yesterday
Report the Spam
This button sends a spam report to the moderator. Please use it sparingly. For other removal requests, read this.
Are you sure? yes no

[PATCH v2 2/4] drm/nouveau: propagate errors from vm flushes

Ad
Marcin Slusarz 1335388916Wed, 25 Apr 2012 21:21:56 +0000 (UTC)
We need this for lockup recovery.

Signed-off-by: Marcin Slusarz 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c  |    9 +++++++--
 drivers/gpu/drm/nouveau/nouveau_drv.h |    6 +++---
 drivers/gpu/drm/nouveau/nouveau_vm.c  |   20 ++++++++++----------
 drivers/gpu/drm/nouveau/nouveau_vm.h  |   18 +++++++++---------
 drivers/gpu/drm/nouveau/nv50_fifo.c   |    4 ++--
 drivers/gpu/drm/nouveau/nv50_graph.c  |   12 ++++++++----
 drivers/gpu/drm/nouveau/nv50_mpeg.c   |    4 ++--
 drivers/gpu/drm/nouveau/nv50_vm.c     |   30 ++++++++++++++++++++----------
 drivers/gpu/drm/nouveau/nv84_crypt.c  |    4 ++--
 drivers/gpu/drm/nouveau/nva3_copy.c   |    4 ++--
 drivers/gpu/drm/nouveau/nvc0_vm.c     |    3 ++-
 11 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 638ae32..5b0dc50 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1230,10 +1230,15 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm,
 		return ret; 	if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
-		nouveau_vm_map(vma, nvbo->bo.mem.mm_node);
+		ret = nouveau_vm_map(vma, nvbo->bo.mem.mm_node);
 	else
 	if (nvbo->bo.mem.mem_type == TTM_PL_TT)
-		nouveau_vm_map_sg(vma, 0, size, node);
+		ret = nouveau_vm_map_sg(vma, 0, size, node);
+
+	if (ret) {
+		nouveau_vm_put(vma);
+		return ret;
+	} 	list_add_tail(&vma->head, &nvbo->vma_list);
 	vma->refcount = 1;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 2f8e80a..d120baf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -320,7 +320,7 @@ struct nouveau_exec_engine {
 	int  (*object_new)(struct nouveau_channel *, int engine,
 			   u32 handle, u16 class);
 	void (*set_tile_region)(struct drm_device *dev, int i);
-	void (*tlb_flush)(struct drm_device *, int engine);
+	int (*tlb_flush)(struct drm_device *, int engine);
 }; struct nouveau_instmem_engine {
@@ -387,7 +387,7 @@ struct nouveau_fifo_engine {
 	void (*destroy_context)(struct nouveau_channel *);
 	int  (*load_context)(struct nouveau_channel *);
 	int  (*unload_context)(struct drm_device *);
-	void (*tlb_flush)(struct drm_device *dev);
+	int  (*tlb_flush)(struct drm_device *dev);
 }; struct nouveau_display_engine {
@@ -1246,7 +1246,7 @@ extern int  nv50_fifo_create_context(struct nouveau_channel *);
 extern void nv50_fifo_destroy_context(struct nouveau_channel *);
 extern int  nv50_fifo_load_context(struct nouveau_channel *);
 extern int  nv50_fifo_unload_context(struct drm_device *);
-extern void nv50_fifo_tlb_flush(struct drm_device *dev);
+extern int  nv50_fifo_tlb_flush(struct drm_device *dev); /* nvc0_fifo.c */
 extern int  nvc0_fifo_init(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c
index 2bf6c03..e2d4853 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.c
@@ -27,7 +27,7 @@
 #include "nouveau_mm.h"
 #include "nouveau_vm.h"-void
+int
 nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
 {
 	struct nouveau_vm *vm = vma->vm;
@@ -67,16 +67,16 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
 		}
 	}-	vm->flush(vm);
+	return vm->flush(vm);
 }-void
+int
 nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_mem *node)
 {
-	nouveau_vm_map_at(vma, 0, node);
+	return nouveau_vm_map_at(vma, 0, node);
 }-void
+int
 nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
 		  struct nouveau_mem *mem)
 {
@@ -110,10 +110,10 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
 		}
 	}-	vm->flush(vm);
+	return vm->flush(vm);
 }-void
+int
 nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
 {
 	struct nouveau_vm *vm = vma->vm;
@@ -144,13 +144,13 @@ nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
 		}
 	}-	vm->flush(vm);
+	return vm->flush(vm);
 }-void
+int
 nouveau_vm_unmap(struct nouveau_vma *vma)
 {
-	nouveau_vm_unmap_at(vma, 0, (u64)vma->node->length << 12);
+	return nouveau_vm_unmap_at(vma, 0, (u64)vma->node->length << 12);
 } static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h
index 4fb6e72..59dc206 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.h
@@ -73,7 +73,7 @@ struct nouveau_vm {
 	void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *,
 		       struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
 	void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt);
-	void (*flush)(struct nouveau_vm *);
+	int (*flush)(struct nouveau_vm *);
 }; /* nouveau_vm.c */
@@ -84,11 +84,11 @@ int  nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **,
 int  nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift,
 		    u32 access, struct nouveau_vma *);
 void nouveau_vm_put(struct nouveau_vma *);
-void nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *);
-void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *);
-void nouveau_vm_unmap(struct nouveau_vma *);
-void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length);
-void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length,
+int  nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *);
+int  nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *);
+int  nouveau_vm_unmap(struct nouveau_vma *);
+int  nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length);
+int  nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length,
 		       struct nouveau_mem *); /* nv50_vm.c */
@@ -99,8 +99,8 @@ void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
 void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
 		    struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
 void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
-void nv50_vm_flush(struct nouveau_vm *);
-void nv50_vm_flush_engine(struct drm_device *, int engine);
+int  nv50_vm_flush(struct nouveau_vm *);
+int  nv50_vm_flush_engine(struct drm_device *, int engine); /* nvc0_vm.c */
 void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
@@ -110,6 +110,6 @@ void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
 void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
 		    struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
 void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
-void nvc0_vm_flush(struct nouveau_vm *);
+int  nvc0_vm_flush(struct nouveau_vm *); #endif
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
index 3bc2a56..3438fc2 100644
--- a/drivers/gpu/drm/nouveau/nv50_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
@@ -499,8 +499,8 @@ nv50_fifo_unload_context(struct drm_device *dev)
 	return 0;
 }-void
+int
 nv50_fifo_tlb_flush(struct drm_device *dev)
 {
-	nv50_vm_flush_engine(dev, 5);
+	return nv50_vm_flush_engine(dev, 5);
 }
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index 2698d80..6899547 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -397,13 +397,13 @@ nv50_graph_nvsw_mthd_page_flip(struct nouveau_channel *chan,
 } 
-static void
+static int
 nv50_graph_tlb_flush(struct drm_device *dev, int engine)
 {
-	nv50_vm_flush_engine(dev, 0);
+	return nv50_vm_flush_engine(dev, 0);
 }-static void
+static int
 nv84_graph_tlb_flush(struct drm_device *dev, int engine)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -412,6 +412,7 @@ nv84_graph_tlb_flush(struct drm_device *dev, int engine)
 	unsigned long flags;
 	u64 start;
 	u32 tmp;
+	int ret = 0; 	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
 	nv_mask(dev, 0x400500, 0x00000001, 0x00000000);
@@ -441,12 +442,15 @@ nv84_graph_tlb_flush(struct drm_device *dev, int engine)
 			      "0x%08x 0x%08x 0x%08x 0x%08x\n",
 			 nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380),
 			 nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388));
+		ret = -EIO;
 	}-	nv50_vm_flush_engine(dev, 0);
+	if (!ret)
+		ret = nv50_vm_flush_engine(dev, 0); 	nv_mask(dev, 0x400500, 0x00000001, 0x00000001);
 	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+	return ret;
 } static struct nouveau_enum nv50_mp_exec_error_names[] = {
diff --git a/drivers/gpu/drm/nouveau/nv50_mpeg.c b/drivers/gpu/drm/nouveau/nv50_mpeg.c
index b57a2d1..1730611 100644
--- a/drivers/gpu/drm/nouveau/nv50_mpeg.c
+++ b/drivers/gpu/drm/nouveau/nv50_mpeg.c
@@ -128,10 +128,10 @@ nv50_mpeg_object_new(struct nouveau_channel *chan, int engine,
 	return ret;
 }-static void
+static int
 nv50_mpeg_tlb_flush(struct drm_device *dev, int engine)
 {
-	nv50_vm_flush_engine(dev, 0x08);
+	return nv50_vm_flush_engine(dev, 0x08);
 } static int
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c
index 44fbac9..6b8df85 100644
--- a/drivers/gpu/drm/nouveau/nv50_vm.c
+++ b/drivers/gpu/drm/nouveau/nv50_vm.c
@@ -142,38 +142,48 @@ nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
 	}
 }-void
+int
 nv50_vm_flush(struct nouveau_vm *vm)
 {
 	struct drm_nouveau_private *dev_priv = vm->dev->dev_private;
 	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
 	int i;
+	int ret; 	pinstmem->flush(vm->dev); 	/* BAR */
-	if (vm == dev_priv->bar1_vm || vm == dev_priv->bar3_vm) {
-		nv50_vm_flush_engine(vm->dev, 6);
-		return;
-	}
+	if (vm == dev_priv->bar1_vm || vm == dev_priv->bar3_vm)
+		return nv50_vm_flush_engine(vm->dev, 6);
+
+	ret = pfifo->tlb_flush(vm->dev);
+	if (ret)
+		return ret;-	pfifo->tlb_flush(vm->dev);
 	for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
-		if (atomic_read(&vm->engref[i]))
-			dev_priv->eng[i]->tlb_flush(vm->dev, i);
+		if (atomic_read(&vm->engref[i])) {
+			ret = dev_priv->eng[i]->tlb_flush(vm->dev, i);
+			if (ret)
+				break;
+		}
 	}
+	return ret;
 }-void
+int
 nv50_vm_flush_engine(struct drm_device *dev, int engine)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	unsigned long flags;
+	int ret = 0; 	spin_lock_irqsave(&dev_priv->vm_lock, flags);
 	nv_wr32(dev, 0x100c80, (engine << 16) | 1);
-	if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000))
+	if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) {
 		NV_ERROR(dev, "vm flush timeout: engine %d\n", engine);
+		ret = -EIO;
+	}
 	spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
+	return ret;
 }
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
index edece9c..6b8b78e 100644
--- a/drivers/gpu/drm/nouveau/nv84_crypt.c
+++ b/drivers/gpu/drm/nouveau/nv84_crypt.c
@@ -111,10 +111,10 @@ nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
 	return ret;
 }-static void
+static int
 nv84_crypt_tlb_flush(struct drm_device *dev, int engine)
 {
-	nv50_vm_flush_engine(dev, 0x0a);
+	return nv50_vm_flush_engine(dev, 0x0a);
 } static void
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.c b/drivers/gpu/drm/nouveau/nva3_copy.c
index 8f356d5..c116e73 100644
--- a/drivers/gpu/drm/nouveau/nva3_copy.c
+++ b/drivers/gpu/drm/nouveau/nva3_copy.c
@@ -105,10 +105,10 @@ nva3_copy_context_del(struct nouveau_channel *chan, int engine)
 	chan->engctx[engine] = ctx;
 }-static void
+static int
 nva3_copy_tlb_flush(struct drm_device *dev, int engine)
 {
-	nv50_vm_flush_engine(dev, 0x0d);
+	return nv50_vm_flush_engine(dev, 0x0d);
 } static int
diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c
index 30d2bd5..1f6fbff 100644
--- a/drivers/gpu/drm/nouveau/nvc0_vm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_vm.c
@@ -99,7 +99,7 @@ nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
 	}
 }-void
+int
 nvc0_vm_flush(struct nouveau_vm *vm)
 {
 	struct drm_nouveau_private *dev_priv = vm->dev->dev_private;
@@ -133,4 +133,5 @@ nvc0_vm_flush(struct nouveau_vm *vm)
 		}
 	}
 	spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
+	return 0;
 }-- 
1.7.8.5
Marcin Slusarz 1338147567Sun, 27 May 2012 19:39:27 +0000 (UTC)
From: Marcin Slusarz 
Subject: [PATCH v3] drm/nouveau: propagate errors from vm flushes

Signed-off-by: Marcin Slusarz 
---
v3: rebased on top of current nouveau-git
---
 drivers/gpu/drm/nouveau/nouveau_bo.c   |    9 +++++++--
 drivers/gpu/drm/nouveau/nouveau_drv.h  |    2 +-
 drivers/gpu/drm/nouveau/nouveau_fifo.h |    2 +-
 drivers/gpu/drm/nouveau/nouveau_vm.c   |   20 ++++++++++----------
 drivers/gpu/drm/nouveau/nouveau_vm.h   |   20 ++++++++++----------
 drivers/gpu/drm/nouveau/nv50_fifo.c    |    4 ++--
 drivers/gpu/drm/nouveau/nv50_graph.c   |   12 ++++++++----
 drivers/gpu/drm/nouveau/nv50_mpeg.c    |    4 ++--
 drivers/gpu/drm/nouveau/nv50_vm.c      |   16 ++++++++++++----
 drivers/gpu/drm/nouveau/nv84_crypt.c   |    4 ++--
 drivers/gpu/drm/nouveau/nv98_crypt.c   |    4 ++--
 drivers/gpu/drm/nouveau/nva3_copy.c    |    4 ++--
 drivers/gpu/drm/nouveau/nvc0_vm.c      |   14 +++++++++++---
 13 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index ab15f5e..f30a75a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -1427,10 +1427,15 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm,
 		return ret; 	if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
-		nouveau_vm_map(vma, nvbo->bo.mem.mm_node);
+		ret = nouveau_vm_map(vma, nvbo->bo.mem.mm_node);
 	else
 	if (nvbo->bo.mem.mem_type == TTM_PL_TT)
-		nouveau_vm_map_sg(vma, 0, size, node);
+		ret = nouveau_vm_map_sg(vma, 0, size, node);
+
+	if (ret) {
+		nouveau_vm_put(vma);
+		return ret;
+	} 	list_add_tail(&vma->head, &nvbo->vma_list);
 	vma->refcount = 1;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index b800c79..c1539b5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -125,7 +125,7 @@ struct nouveau_engine {
 	int  (*object_new)(struct nouveau_channel *, int engine,
 			   u32 handle, u16 class);
 	void (*set_tile_region)(struct nouveau_device *, int i);
-	void (*tlb_flush)(struct nouveau_device *, int engine);
+	int  (*tlb_flush)(struct nouveau_device *, int engine);
 }; #define nouveau_engine_create(ndev,engine,sstr,fstr,data)                      \
diff --git a/drivers/gpu/drm/nouveau/nouveau_fifo.h b/drivers/gpu/drm/nouveau/nouveau_fifo.h
index 13a96ef..c2fb136 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fifo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fifo.h
@@ -20,7 +20,7 @@ void nv04_fifo_ramht(struct nouveau_device *, struct nouveau_ramht **); void nv50_fifo_playlist_update(struct nouveau_device *);
 void nv50_fifo_destroy(struct nouveau_device *, int);
-void nv50_fifo_tlb_flush(struct nouveau_device *, int);
+int  nv50_fifo_tlb_flush(struct nouveau_device *, int); int  nv04_fifo_create(struct nouveau_device *, int engine);
 int  nv10_fifo_create(struct nouveau_device *, int engine);
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c
index 2678a0b7..e3cd453 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.c
@@ -29,7 +29,7 @@
 #include "nouveau_vm.h"
 #include "nouveau_gpuobj.h"-void
+int
 nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
 {
 	struct nouveau_vm *vm = vma->vm;
@@ -69,16 +69,16 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_mem *node)
 		}
 	}-	vm->flush(vm);
+	return vm->flush(vm);
 }-void
+int
 nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_mem *node)
 {
-	nouveau_vm_map_at(vma, 0, node);
+	return nouveau_vm_map_at(vma, 0, node);
 }-void
+int
 nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
 		  struct nouveau_mem *mem)
 {
@@ -112,10 +112,10 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length,
 		}
 	}-	vm->flush(vm);
+	return vm->flush(vm);
 }-void
+int
 nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
 {
 	struct nouveau_vm *vm = vma->vm;
@@ -146,13 +146,13 @@ nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length)
 		}
 	}-	vm->flush(vm);
+	return vm->flush(vm);
 }-void
+int
 nouveau_vm_unmap(struct nouveau_vma *vma)
 {
-	nouveau_vm_unmap_at(vma, 0, (u64)vma->node->length << 12);
+	return nouveau_vm_unmap_at(vma, 0, (u64)vma->node->length << 12);
 } static void
diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h
index 93a975e..f3bd0a5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_vm.h
@@ -73,7 +73,7 @@ struct nouveau_vm {
 	void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *,
 		       struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
 	void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt);
-	void (*flush)(struct nouveau_vm *);
+	int (*flush)(struct nouveau_vm *);
 }; /* nouveau_vm.c */
@@ -84,11 +84,11 @@ int  nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **,
 int  nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift,
 		    u32 access, struct nouveau_vma *);
 void nouveau_vm_put(struct nouveau_vma *);
-void nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *);
-void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *);
-void nouveau_vm_unmap(struct nouveau_vma *);
-void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length);
-void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length,
+int  nouveau_vm_map(struct nouveau_vma *, struct nouveau_mem *);
+int  nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_mem *);
+int  nouveau_vm_unmap(struct nouveau_vma *);
+int  nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length);
+int  nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length,
 		       struct nouveau_mem *); /* nv50_vm.c */
@@ -99,8 +99,8 @@ void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
 void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
 		    struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
 void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
-void nv50_vm_flush(struct nouveau_vm *);
-void nv50_vm_flush_engine(struct nouveau_device *, int engine);
+int  nv50_vm_flush(struct nouveau_vm *);
+int  nv50_vm_flush_engine(struct nouveau_device *, int engine); /* nvc0_vm.c */
 void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
@@ -110,7 +110,7 @@ void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *,
 void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *,
 		    struct nouveau_mem *, u32 pte, u32 cnt, dma_addr_t *);
 void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt);
-void nvc0_vm_flush(struct nouveau_vm *);
-void nvc0_vm_flush_engine(struct nouveau_device *, u64 addr, u32 type);
+int  nvc0_vm_flush(struct nouveau_vm *);
+int  nvc0_vm_flush_engine(struct nouveau_device *, u64 addr, u32 type); #endif
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c
index a59094d..81271ee 100644
--- a/drivers/gpu/drm/nouveau/nv50_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv50_fifo.c
@@ -229,10 +229,10 @@ nv50_fifo_fini(struct nouveau_device *ndev, int engine, bool suspend)
 	return 0;
 }-void
+int
 nv50_fifo_tlb_flush(struct nouveau_device *ndev, int engine)
 {
-	nv50_vm_flush_engine(ndev, 5);
+	return nv50_vm_flush_engine(ndev, 5);
 } void
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c
index 4fe58eb..78365fe 100644
--- a/drivers/gpu/drm/nouveau/nv50_graph.c
+++ b/drivers/gpu/drm/nouveau/nv50_graph.c
@@ -205,13 +205,13 @@ nv50_graph_object_new(struct nouveau_channel *chan, int engine,
 	return ret;
 }-static void
+static int
 nv50_graph_tlb_flush(struct nouveau_device *ndev, int engine)
 {
-	nv50_vm_flush_engine(ndev, 0);
+	return nv50_vm_flush_engine(ndev, 0);
 }-static void
+static int
 nv84_graph_tlb_flush(struct nouveau_device *ndev, int engine)
 {
 	struct nouveau_timer *ptimer = nv_subdev(ndev, NVDEV_SUBDEV_TIMER);
@@ -219,6 +219,7 @@ nv84_graph_tlb_flush(struct nouveau_device *ndev, int engine)
 	unsigned long flags;
 	u64 start;
 	u32 tmp;
+	int ret = 0; 	spin_lock_irqsave(&ndev->context_switch_lock, flags);
 	nv_mask(ndev, 0x400500, 0x00000001, 0x00000000);
@@ -249,12 +250,15 @@ nv84_graph_tlb_flush(struct nouveau_device *ndev, int engine)
 			      "0x%08x 0x%08x 0x%08x 0x%08x\n",
 			 nv_rd32(ndev, 0x400700), nv_rd32(ndev, 0x400380),
 			 nv_rd32(ndev, 0x400384), nv_rd32(ndev, 0x400388));
+		ret = -EIO;
 	}-	nv50_vm_flush_engine(ndev, 0);
+	if (!ret)
+		ret = nv50_vm_flush_engine(ndev, 0); 	nv_mask(ndev, 0x400500, 0x00000001, 0x00000001);
 	spin_unlock_irqrestore(&ndev->context_switch_lock, flags);
+	return ret;
 } static struct nouveau_enum nv50_mp_exec_error_names[] = {
diff --git a/drivers/gpu/drm/nouveau/nv50_mpeg.c b/drivers/gpu/drm/nouveau/nv50_mpeg.c
index 9a0e80b..2f3325c 100644
--- a/drivers/gpu/drm/nouveau/nv50_mpeg.c
+++ b/drivers/gpu/drm/nouveau/nv50_mpeg.c
@@ -115,10 +115,10 @@ nv50_mpeg_object_new(struct nouveau_channel *chan, int engine,
 	return ret;
 }-static void
+static int
 nv50_mpeg_tlb_flush(struct nouveau_device *ndev, int engine)
 {
-	nv50_vm_flush_engine(ndev, 0x08);
+	return nv50_vm_flush_engine(ndev, 0x08);
 } static int
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c
index a5be4cf..31138b4 100644
--- a/drivers/gpu/drm/nouveau/nv50_vm.c
+++ b/drivers/gpu/drm/nouveau/nv50_vm.c
@@ -146,30 +146,38 @@ nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
 	}
 }-void
+int
 nv50_vm_flush(struct nouveau_vm *vm)
 {
 	struct nouveau_device *ndev = vm->device;
 	int i;
+	int ret = 0; 	nouveau_instmem_flush(ndev); 	for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
 		if (atomic_read(&vm->engref[i])) {
 			struct nouveau_engine *engine = nv_engine(ndev, i);
-			engine->tlb_flush(ndev, i);
+			ret = engine->tlb_flush(ndev, i);
+			if (ret)
+				break;
 		}
 	}
+	return ret;
 }-void
+int
 nv50_vm_flush_engine(struct nouveau_device *ndev, int engine)
 {
 	unsigned long flags;
+	int ret = 0; 	spin_lock_irqsave(&ndev->vm_lock, flags);
 	nv_wr32(ndev, 0x100c80, (engine << 16) | 1);
-	if (!nv_wait(ndev, 0x100c80, 0x00000001, 0x00000000))
+	if (!nv_wait(ndev, 0x100c80, 0x00000001, 0x00000000)) {
 		NV_ERROR(ndev, "vm flush timeout: engine %d\n", engine);
+		ret = -EIO;
+	}
 	spin_unlock_irqrestore(&ndev->vm_lock, flags);
+	return ret;
 }
diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c
index 38dc6fc..6059f0e 100644
--- a/drivers/gpu/drm/nouveau/nv84_crypt.c
+++ b/drivers/gpu/drm/nouveau/nv84_crypt.c
@@ -114,10 +114,10 @@ nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
 	return ret;
 }-static void
+static int
 nv84_crypt_tlb_flush(struct nouveau_device *ndev, int engine)
 {
-	nv50_vm_flush_engine(ndev, 0x0a);
+	return nv50_vm_flush_engine(ndev, 0x0a);
 } static void
diff --git a/drivers/gpu/drm/nouveau/nv98_crypt.c b/drivers/gpu/drm/nouveau/nv98_crypt.c
index ef2ff44..c42e41c 100644
--- a/drivers/gpu/drm/nouveau/nv98_crypt.c
+++ b/drivers/gpu/drm/nouveau/nv98_crypt.c
@@ -105,10 +105,10 @@ nv98_crypt_object_new(struct nouveau_channel *chan, int engine,
 	return nouveau_ramht_insert(chan, handle, cctx->mem);
 }-static void
+static int
 nv98_crypt_tlb_flush(struct nouveau_device *ndev, int engine)
 {
-	nv50_vm_flush_engine(ndev, 0x0a);
+	return nv50_vm_flush_engine(ndev, 0x0a);
 } static int
diff --git a/drivers/gpu/drm/nouveau/nva3_copy.c b/drivers/gpu/drm/nouveau/nva3_copy.c
index 87c3580..6e6482f 100644
--- a/drivers/gpu/drm/nouveau/nva3_copy.c
+++ b/drivers/gpu/drm/nouveau/nva3_copy.c
@@ -95,10 +95,10 @@ nva3_copy_context_del(struct nouveau_channel *chan, int engine)
 	chan->engctx[engine] = ctx;
 }-static void
+static int
 nva3_copy_tlb_flush(struct nouveau_device *ndev, int engine)
 {
-	nv50_vm_flush_engine(ndev, 0x0d);
+	return nv50_vm_flush_engine(ndev, 0x0d);
 } static int
diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c
index cc7096a..7301a5f 100644
--- a/drivers/gpu/drm/nouveau/nvc0_vm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_vm.c
@@ -101,10 +101,11 @@ nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
 	}
 }-void
+int
 nvc0_vm_flush_engine(struct nouveau_device *ndev, u64 addr, u32 type)
 {
 	unsigned long flags;
+	int ret = 0; 	/* looks like maybe a "free flush slots" counter, the
 	 * faster you write to 0x100cbc to more it decreases
@@ -113,6 +114,7 @@ nvc0_vm_flush_engine(struct nouveau_device *ndev, u64 addr, u32 type)
 	if (!nv_wait_ne(ndev, 0x100c80, 0x00ff0000, 0x00000000)) {
 		NV_ERROR(ndev, "vm timeout 0: 0x%08x %d\n",
 			 nv_rd32(ndev, 0x100c80), type);
+		ret = -EIO;
 	} 	nv_wr32(ndev, 0x100cb8, addr >> 8);
@@ -122,19 +124,25 @@ nvc0_vm_flush_engine(struct nouveau_device *ndev, u64 addr, u32 type)
 	if (!nv_wait(ndev, 0x100c80, 0x00008000, 0x00008000)) {
 		NV_ERROR(ndev, "vm timeout 1: 0x%08x %d\n",
 			 nv_rd32(ndev, 0x100c80), type);
+		ret = -EIO;
 	}
 	spin_unlock_irqrestore(&ndev->vm_lock, flags);
+	return ret;
 }-void
+int
 nvc0_vm_flush(struct nouveau_vm *vm)
 {
 	struct nouveau_device *ndev = vm->device;
 	struct nouveau_vm_pgd *vpgd;
+	int ret = 0; 	nouveau_instmem_flush(ndev); 	list_for_each_entry(vpgd, &vm->pgd_list, head) {
-		nvc0_vm_flush_engine(ndev, vpgd->obj->vinst, 1);
+		ret = nvc0_vm_flush_engine(ndev, vpgd->obj->vinst, 1);
+		if (ret)
+			break;
 	}
+	return ret;
 }-- 
1.7.8.6
Home | About | Privacy