[08/14] drm/i915/error: Capture vmas instead of BOs

Submitted by Michel Thierry on July 15, 2014, 4:20 p.m.

Details

Message ID 1405441251-28744-9-git-send-email-michel.thierry@intel.com
State New, archived
Headers show

Not browsing as part of any series.

Commit Message

Michel Thierry July 15, 2014, 4:20 p.m.
From: Ben Widawsky <benjamin.widawsky@intel.com>

To follow up on the last patch, we can now capture the VMAs instead of
the BOs. The hope if we get more accurate error capture while debugging
PPGTT.

Note that this does not impact the previous argument about whether to
capture all VMAs, or just the guilty VMA. This merely allows the code to
do whatever we chose later.

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
---
 drivers/gpu/drm/i915/i915_drv.h       |  1 +
 drivers/gpu/drm/i915/i915_gpu_error.c | 53 +++++++++++++++++++----------------
 2 files changed, 30 insertions(+), 24 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 991b663..96cf5a9 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -309,6 +309,7 @@  struct drm_i915_error_state {
 	char error_msg[128];
 	u32 reset_count;
 	u32 suspend_count;
+	u32 vm_count;
 
 	/* Generic register state */
 	u32 eir;
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 4ff819e..eb943ee 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -385,15 +385,19 @@  int i915_error_state_to_str(struct drm_i915_error_state_buf *m,
 		i915_ring_error_state(m, dev, &error->ring[i]);
 	}
 
-	if (error->active_bo)
-		print_error_buffers(m, "Active",
-				    error->active_bo[0],
-				    error->active_bo_count[0]);
+	for (i = 0; i < error->vm_count; i++) {
+		if (error->active_bo[i])
+			print_error_buffers(m, "Active",
+					    error->active_bo[i],
+					    error->active_bo_count[i]);
+	}
 
-	if (error->pinned_bo)
-		print_error_buffers(m, "Pinned",
-				    error->pinned_bo[0],
-				    error->pinned_bo_count[0]);
+	for (i = 0; i < error->vm_count; i++) {
+		if (error->pinned_bo[i])
+			print_error_buffers(m, "Pinned",
+					    error->pinned_bo[i],
+					    error->pinned_bo_count[i]);
+	}
 
 	for (i = 0; i < ARRAY_SIZE(error->ring); i++) {
 		obj = error->ring[i].batchbuffer;
@@ -635,22 +639,23 @@  unwind:
 	i915_error_object_create_sized((dev_priv), (src), &(dev_priv)->gtt.base, \
 				       (src)->base.size>>PAGE_SHIFT)
 
-static void capture_bo(struct drm_i915_error_buffer *err,
-		       struct drm_i915_gem_object *obj)
+static void capture_vma(struct drm_i915_error_buffer *err, struct i915_vma *vma)
 {
+	struct drm_i915_gem_object *obj = vma->obj;
+
 	err->size = obj->base.size;
 	err->name = obj->base.name;
 	err->rseqno = obj->last_read_seqno;
 	err->wseqno = obj->last_write_seqno;
-	err->gtt_offset = i915_gem_obj_ggtt_offset(obj);
+	err->gtt_offset = vma->node.start;
 	err->read_domains = obj->base.read_domains;
 	err->write_domain = obj->base.write_domain;
 	err->fence_reg = obj->fence_reg;
-	err->pinned = 0;
-	if (i915_gem_obj_is_pinned(obj))
-		err->pinned = 1;
-	if (obj->user_pin_count > 0)
+	if (obj->user_pin_count > 0) {
+		WARN_ON(i915_is_ggtt(vma->vm));
 		err->pinned = -1;
+	} else
+		err->pinned = !!vma->pin_count;
 	err->tiling = obj->tiling_mode;
 	err->dirty = obj->dirty;
 	err->purgeable = obj->madv != I915_MADV_WILLNEED;
@@ -666,7 +671,7 @@  static u32 capture_active_bo(struct drm_i915_error_buffer *err,
 	int i = 0;
 
 	list_for_each_entry(vma, head, mm_list) {
-		capture_bo(err++, vma->obj);
+		capture_vma(err++, vma);
 		if (++i == count)
 			break;
 	}
@@ -681,10 +686,10 @@  static u32 capture_pinned_bo(struct drm_i915_error_buffer *err,
 	int i = 0;
 
 	list_for_each_entry(vma, head, pin_capture_link) {
-		if (!i915_gem_obj_is_pinned(vma->obj))
+		if (!vma->pin_count)
 			continue;
 
-		capture_bo(err++, vma->obj);
+		capture_vma(err++, vma);
 		if (++i == count)
 			break;
 	}
@@ -1083,16 +1088,16 @@  static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv,
 				     struct drm_i915_error_state *error)
 {
 	struct i915_address_space *vm;
-	int vm_count = 0, i = 0;
+	int i = 0;
 
 	list_for_each_entry(vm, &dev_priv->vm_list, global_link)
-		vm_count++;
+		error->vm_count++;
 
-	error->active_bo = kcalloc(vm_count, sizeof(*error->active_bo), GFP_ATOMIC);
-	error->pinned_bo = kcalloc(vm_count, sizeof(*error->pinned_bo), GFP_ATOMIC);
-	error->active_bo_count = kcalloc(vm_count, sizeof(*error->active_bo_count),
+	error->active_bo = kcalloc(error->vm_count, sizeof(*error->active_bo), GFP_ATOMIC);
+	error->pinned_bo = kcalloc(error->vm_count, sizeof(*error->pinned_bo), GFP_ATOMIC);
+	error->active_bo_count = kcalloc(error->vm_count, sizeof(*error->active_bo_count),
 					 GFP_ATOMIC);
-	error->pinned_bo_count = kcalloc(vm_count, sizeof(*error->pinned_bo_count),
+	error->pinned_bo_count = kcalloc(error->vm_count, sizeof(*error->pinned_bo_count),
 					 GFP_ATOMIC);
 
 	list_for_each_entry(vm, &dev_priv->vm_list, global_link)