diff options
author | Ben Widawsky <ben@bwidawsk.net> | 2014-06-30 12:53:41 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-07 17:16:54 -0400 |
commit | 0ca36d78391dc97b7d3e3d26e4518e30f3e88c16 (patch) | |
tree | bfb229c131b226be5761aebee7df39e0bfb912a0 /drivers/gpu/drm/i915/i915_gpu_error.c | |
parent | 87f85ebc8dd089842e9efafd811486e5997b2265 (diff) |
drm/i915/bdw: collect semaphore error state
Since the semaphore information is in an object, just dump it, and let
the user parse it later.
NOTE: The page being used for the semaphores are incoherent with the
CPU. No matter what I do, I cannot figure out a way to read anything but
0s. Note that the semaphore waits are indeed working.
v2: Don't print signal, and wait (they should be the same). Instead,
print sync_seqno (Chris)
v3: Free the semaphore error object (Chris)
v4: Fix semaphore offset calculation during error state collection
(Ville)
v5: VCS2 rebase
Make semaphore object error capture coding style consistent (Ville)
Do the proper math for the signal offset (Ville)
v6: Fix small conflicts on rebase and s/ring_buffer/engine_cs (Rodrigo)
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gpu_error.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gpu_error.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 9d42b6a8b545..45b6191efb58 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
@@ -327,6 +327,7 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
327 | struct drm_device *dev = error_priv->dev; | 327 | struct drm_device *dev = error_priv->dev; |
328 | struct drm_i915_private *dev_priv = dev->dev_private; | 328 | struct drm_i915_private *dev_priv = dev->dev_private; |
329 | struct drm_i915_error_state *error = error_priv->error; | 329 | struct drm_i915_error_state *error = error_priv->error; |
330 | struct drm_i915_error_object *obj; | ||
330 | int i, j, offset, elt; | 331 | int i, j, offset, elt; |
331 | int max_hangcheck_score; | 332 | int max_hangcheck_score; |
332 | 333 | ||
@@ -395,8 +396,6 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
395 | error->pinned_bo_count[0]); | 396 | error->pinned_bo_count[0]); |
396 | 397 | ||
397 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { | 398 | for (i = 0; i < ARRAY_SIZE(error->ring); i++) { |
398 | struct drm_i915_error_object *obj; | ||
399 | |||
400 | obj = error->ring[i].batchbuffer; | 399 | obj = error->ring[i].batchbuffer; |
401 | if (obj) { | 400 | if (obj) { |
402 | err_puts(m, dev_priv->ring[i].name); | 401 | err_puts(m, dev_priv->ring[i].name); |
@@ -459,6 +458,18 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, | |||
459 | } | 458 | } |
460 | } | 459 | } |
461 | 460 | ||
461 | if ((obj = error->semaphore_obj)) { | ||
462 | err_printf(m, "Semaphore page = 0x%08x\n", obj->gtt_offset); | ||
463 | for (elt = 0; elt < PAGE_SIZE/16; elt += 4) { | ||
464 | err_printf(m, "[%04x] %08x %08x %08x %08x\n", | ||
465 | elt * 4, | ||
466 | obj->pages[0][elt], | ||
467 | obj->pages[0][elt+1], | ||
468 | obj->pages[0][elt+2], | ||
469 | obj->pages[0][elt+3]); | ||
470 | } | ||
471 | } | ||
472 | |||
462 | if (error->overlay) | 473 | if (error->overlay) |
463 | intel_overlay_print_error_state(m, error->overlay); | 474 | intel_overlay_print_error_state(m, error->overlay); |
464 | 475 | ||
@@ -529,6 +540,7 @@ static void i915_error_state_free(struct kref *error_ref) | |||
529 | kfree(error->ring[i].requests); | 540 | kfree(error->ring[i].requests); |
530 | } | 541 | } |
531 | 542 | ||
543 | i915_error_object_free(error->semaphore_obj); | ||
532 | kfree(error->active_bo); | 544 | kfree(error->active_bo); |
533 | kfree(error->overlay); | 545 | kfree(error->overlay); |
534 | kfree(error->display); | 546 | kfree(error->display); |
@@ -747,6 +759,33 @@ static void i915_gem_record_fences(struct drm_device *dev, | |||
747 | } | 759 | } |
748 | 760 | ||
749 | 761 | ||
762 | static void gen8_record_semaphore_state(struct drm_i915_private *dev_priv, | ||
763 | struct drm_i915_error_state *error, | ||
764 | struct intel_engine_cs *ring, | ||
765 | struct drm_i915_error_ring *ering) | ||
766 | { | ||
767 | struct intel_engine_cs *useless; | ||
768 | int i; | ||
769 | |||
770 | if (!i915_semaphore_is_enabled(dev_priv->dev)) | ||
771 | return; | ||
772 | |||
773 | if (!error->semaphore_obj) | ||
774 | error->semaphore_obj = | ||
775 | i915_error_object_create(dev_priv, | ||
776 | dev_priv->semaphore_obj, | ||
777 | &dev_priv->gtt.base); | ||
778 | |||
779 | for_each_ring(useless, dev_priv, i) { | ||
780 | u16 signal_offset = | ||
781 | (GEN8_SIGNAL_OFFSET(ring, i) & PAGE_MASK) / 4; | ||
782 | u32 *tmp = error->semaphore_obj->pages[0]; | ||
783 | |||
784 | ering->semaphore_mboxes[i] = tmp[signal_offset]; | ||
785 | ering->semaphore_seqno[i] = ring->semaphore.sync_seqno[i]; | ||
786 | } | ||
787 | } | ||
788 | |||
750 | static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, | 789 | static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, |
751 | struct intel_engine_cs *ring, | 790 | struct intel_engine_cs *ring, |
752 | struct drm_i915_error_ring *ering) | 791 | struct drm_i915_error_ring *ering) |
@@ -764,6 +803,7 @@ static void gen6_record_semaphore_state(struct drm_i915_private *dev_priv, | |||
764 | } | 803 | } |
765 | 804 | ||
766 | static void i915_record_ring_state(struct drm_device *dev, | 805 | static void i915_record_ring_state(struct drm_device *dev, |
806 | struct drm_i915_error_state *error, | ||
767 | struct intel_engine_cs *ring, | 807 | struct intel_engine_cs *ring, |
768 | struct drm_i915_error_ring *ering) | 808 | struct drm_i915_error_ring *ering) |
769 | { | 809 | { |
@@ -772,7 +812,10 @@ static void i915_record_ring_state(struct drm_device *dev, | |||
772 | if (INTEL_INFO(dev)->gen >= 6) { | 812 | if (INTEL_INFO(dev)->gen >= 6) { |
773 | ering->rc_psmi = I915_READ(ring->mmio_base + 0x50); | 813 | ering->rc_psmi = I915_READ(ring->mmio_base + 0x50); |
774 | ering->fault_reg = I915_READ(RING_FAULT_REG(ring)); | 814 | ering->fault_reg = I915_READ(RING_FAULT_REG(ring)); |
775 | gen6_record_semaphore_state(dev_priv, ring, ering); | 815 | if (INTEL_INFO(dev)->gen >= 8) |
816 | gen8_record_semaphore_state(dev_priv, error, ring, ering); | ||
817 | else | ||
818 | gen6_record_semaphore_state(dev_priv, ring, ering); | ||
776 | } | 819 | } |
777 | 820 | ||
778 | if (INTEL_INFO(dev)->gen >= 4) { | 821 | if (INTEL_INFO(dev)->gen >= 4) { |
@@ -901,7 +944,7 @@ static void i915_gem_record_rings(struct drm_device *dev, | |||
901 | 944 | ||
902 | error->ring[i].valid = true; | 945 | error->ring[i].valid = true; |
903 | 946 | ||
904 | i915_record_ring_state(dev, ring, &error->ring[i]); | 947 | i915_record_ring_state(dev, error, ring, &error->ring[i]); |
905 | 948 | ||
906 | request = i915_gem_find_active_request(ring); | 949 | request = i915_gem_find_active_request(ring); |
907 | if (request) { | 950 | if (request) { |