[PATCH 24/26] drm/radeon: extend ring debugfs files with fence info
Christian König
deathsimple at vodafone.de
Wed Apr 25 05:46:41 PDT 2012
That should aid in debugging multi ring lockups.
Signed-off-by: Christian König <deathsimple at 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
More information about the dri-devel
mailing list