That should aid in debugging multi ring lockups. Signed-off-by: Christian König <deathsimple@xxxxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel