drm/radeon: improve ring lockup detection code v2
authorChristian König <christian.koenig@amd.com>
Tue, 18 Feb 2014 14:24:06 +0000 (15:24 +0100)
committerChristian König <christian.koenig@amd.com>
Fri, 28 Feb 2014 09:53:16 +0000 (10:53 +0100)
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>
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_ring.c

index 4581df193932f1b1ad3c9b66178bdf2a1ee547ec..e98fe5c7f77b6e8d64a1fef8f8df8a82268f2e2c 100644 (file)
@@ -805,8 +805,8 @@ struct radeon_ring {
        unsigned                ring_size;
        unsigned                ring_free_dw;
        int                     count_dw;
-       unsigned long           last_activity;
-       unsigned                last_rptr;
+       atomic_t                last_rptr;
+       atomic64_t              last_activity;
        uint64_t                gpu_addr;
        uint32_t                align_mask;
        uint32_t                ptr_mask;
index b14c86d57607f8e26d444f26de3c941ca813194a..4c481027237120b27aefa7dddecec5060992a4e2 100644 (file)
@@ -485,8 +485,8 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *rin
 void radeon_ring_lockup_update(struct radeon_device *rdev,
                               struct radeon_ring *ring)
 {
-       ring->last_rptr = radeon_ring_get_rptr(rdev, ring);
-       ring->last_activity = jiffies;
+       atomic_set(&ring->last_rptr, radeon_ring_get_rptr(rdev, ring));
+       atomic64_set(&ring->last_activity, jiffies_64);
 }
 
 /**
@@ -498,22 +498,19 @@ void radeon_ring_lockup_update(struct radeon_device *rdev,
 bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
 {
        uint32_t rptr = radeon_ring_get_rptr(rdev, ring);
-       unsigned long cjiffies, elapsed;
+       uint64_t last = atomic64_read(&ring->last_activity);
+       uint64_t elapsed;
 
-       cjiffies = jiffies;
-       if (!time_after(cjiffies, ring->last_activity)) {
-               /* likely a wrap around */
+       if (rptr != atomic_read(&ring->last_rptr)) {
+               /* ring is still working, no lockup */
                radeon_ring_lockup_update(rdev, ring);
                return false;
        }
-       if (rptr != ring->last_rptr) {
-               /* CP is still working no lockup */
-               radeon_ring_lockup_update(rdev, ring);
-               return false;
-       }
-       elapsed = jiffies_to_msecs(cjiffies - ring->last_activity);
+
+       elapsed = jiffies_to_msecs(jiffies_64 - last);
        if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) {
-               dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed);
+               dev_err(rdev->dev, "ring %d stalled for more than %llumsec\n",
+                       ring->idx, elapsed);
                return true;
        }
        /* give a chance to the GPU ... */