aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2014-02-18 09:24:06 -0500
committerChristian König <christian.koenig@amd.com>2014-02-28 04:53:16 -0500
commitaee4aa73a1af3176cc3eea5833cae596b4b7dd22 (patch)
tree47b15679aef32ca0399b18c9ca07eec7ae34461e /drivers/gpu
parent4d538b79197901fecc42e746d515d07fd1089b62 (diff)
drm/radeon: improve ring lockup detection code v2
Use atomics and jiffies_64, so that we don't need to have the ring mutex locked any more and avoid wrap arounds. v2: fix some checkpatch warnings Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c23
2 files changed, 12 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 4581df193932..e98fe5c7f77b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -805,8 +805,8 @@ struct radeon_ring {
805 unsigned ring_size; 805 unsigned ring_size;
806 unsigned ring_free_dw; 806 unsigned ring_free_dw;
807 int count_dw; 807 int count_dw;
808 unsigned long last_activity; 808 atomic_t last_rptr;
809 unsigned last_rptr; 809 atomic64_t last_activity;
810 uint64_t gpu_addr; 810 uint64_t gpu_addr;
811 uint32_t align_mask; 811 uint32_t align_mask;
812 uint32_t ptr_mask; 812 uint32_t ptr_mask;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index b14c86d57607..4c4810272371 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -485,8 +485,8 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *rin
485void radeon_ring_lockup_update(struct radeon_device *rdev, 485void radeon_ring_lockup_update(struct radeon_device *rdev,
486 struct radeon_ring *ring) 486 struct radeon_ring *ring)
487{ 487{
488 ring->last_rptr = radeon_ring_get_rptr(rdev, ring); 488 atomic_set(&ring->last_rptr, radeon_ring_get_rptr(rdev, ring));
489 ring->last_activity = jiffies; 489 atomic64_set(&ring->last_activity, jiffies_64);
490} 490}
491 491
492/** 492/**
@@ -498,22 +498,19 @@ void radeon_ring_lockup_update(struct radeon_device *rdev,
498bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 498bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
499{ 499{
500 uint32_t rptr = radeon_ring_get_rptr(rdev, ring); 500 uint32_t rptr = radeon_ring_get_rptr(rdev, ring);
501 unsigned long cjiffies, elapsed; 501 uint64_t last = atomic64_read(&ring->last_activity);
502 uint64_t elapsed;
502 503
503 cjiffies = jiffies; 504 if (rptr != atomic_read(&ring->last_rptr)) {
504 if (!time_after(cjiffies, ring->last_activity)) { 505 /* ring is still working, no lockup */
505 /* likely a wrap around */
506 radeon_ring_lockup_update(rdev, ring); 506 radeon_ring_lockup_update(rdev, ring);
507 return false; 507 return false;
508 } 508 }
509 if (rptr != ring->last_rptr) { 509
510 /* CP is still working no lockup */ 510 elapsed = jiffies_to_msecs(jiffies_64 - last);
511 radeon_ring_lockup_update(rdev, ring);
512 return false;
513 }
514 elapsed = jiffies_to_msecs(cjiffies - ring->last_activity);
515 if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) { 511 if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) {
516 dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); 512 dev_err(rdev->dev, "ring %d stalled for more than %llumsec\n",
513 ring->idx, elapsed);
517 return true; 514 return true;
518 } 515 }
519 /* give a chance to the GPU ... */ 516 /* give a chance to the GPU ... */