That should aid in debugging multi ring lockups.

Signed-off-by: Christian König <deathsim...@vodafone.de>
---
 drivers/gpu/drm/radeon/radeon.h       |    1 +
 drivers/gpu/drm/radeon/radeon_fence.c |    1 +
 drivers/gpu/drm/radeon/radeon_ring.c  |   43 ++++++++++++++++++++++++++++++++-
 3 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b2d72e2..21b9a75 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -233,6 +233,7 @@ struct radeon_fence {
        bool                            signaled;
        /* RB, DMA, etc. */
        int                             ring;
+       unsigned                        emitted_at;
        struct radeon_semaphore         *semaphore;
        struct radeon_ib                *ib;
 };
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c 
b/drivers/gpu/drm/radeon/radeon_fence.c
index 09e13e3..f8bdef5 100644
--- a/drivers/gpu/drm/radeon/radeon_fence.c
+++ b/drivers/gpu/drm/radeon/radeon_fence.c
@@ -71,6 +71,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct 
radeon_fence *fence)
                return 0;
        }
        fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq);
+       fence->emitted_at = rdev->ring[fence->ring].wptr;
        radeon_fence_ring_emit(rdev, fence->ring, fence);
        trace_radeon_fence_emit(rdev->ddev, fence->seq);
        fence->emitted = true;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c 
b/drivers/gpu/drm/radeon/radeon_ring.c
index 4d1987d..992a615 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -485,8 +485,12 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
        struct radeon_device *rdev = dev->dev_private;
        int ridx = *(int*)node->info_ent->data;
        struct radeon_ring *ring = &rdev->ring[ridx];
+       struct radeon_fence *fence = NULL;
        unsigned count, i, j;
+       unsigned long flags;
 
+       mutex_lock(&ring->mutex);
+       read_lock_irqsave(&rdev->fence_lock, flags);
        radeon_ring_free_size(rdev, ring);
        count = (ring->ring_size / 4) - ring->ring_free_dw;
        seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, 
RREG32(ring->wptr_reg));
@@ -496,10 +500,47 @@ static int radeon_debugfs_ring_info(struct seq_file *m, 
void *data)
        seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw);
        seq_printf(m, "%u dwords in ring\n", count);
        i = ring->rptr;
+       if (!list_empty(&rdev->fence_drv[ridx].emitted)) {
+               fence = list_first_entry(&rdev->fence_drv[ridx].emitted, 
+                                        struct radeon_fence, list);
+
+               if (fence->emitted_at < ring->rptr && (
+                   ring->wptr >= ring->rptr || fence->emitted_at > 
ring->wptr)) {
+
+                       /* if first emitted fence is before current
+                          read pointer, then print that content also */
+                       count = (fence->emitted_at + (ring->ring_size / 4));
+                       count -= ring->wptr;
+                       count &= ring->ptr_mask;
+                       count = (ring->ring_size / 4) - count;
+                       i = fence->emitted_at;
+               }
+       } else {
+               fence = NULL;
+       }
        for (j = 0; j <= count; j++) {
-               seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]);
+               seq_printf(m, "r[%04d]=0x%08x", i, ring->ring[i]);
+               if (i == ring->rptr) {
+                       seq_printf(m, " <- RPTR ");
+               }
+               if (fence && fence->emitted_at == i) {
+                       seq_printf(m, " <- seq 0x%08x", fence->seq);
+                       if (fence->semaphore) {
+                               seq_printf(m, " sem @ 0x%09Lx ",
+                                          (long 
long)fence->semaphore->gpu_addr);
+                       }
+                       if (fence->list.next != &rdev->fence_drv[ridx].emitted) 
{
+                               fence = list_entry(fence->list.next,
+                                                  struct radeon_fence, list);
+                       } else {
+                               fence = NULL;
+                       }
+               }
+               seq_printf(m, "\n");
                i = (i + 1) & ring->ptr_mask;
        }
+       read_unlock_irqrestore(&rdev->fence_lock, flags);
+       mutex_unlock(&ring->mutex);
        return 0;
 }
 
-- 
1.7.5.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to