If we've already seen a fence, don't backup the
ring contents since presumably either the previous reset
was not successful or there was something wrong with the
data.

Signed-off-by: Alex Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 11 +++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h  |  1 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 6a43c8494fa8c..a7a6db0bc6940 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -803,6 +803,17 @@ void amdgpu_ring_backup_unprocessed_commands(struct 
amdgpu_ring *ring,
        seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
        ring->ring_backup_entries_to_copy = 0;
 
+       /* if we've already seen this fence, return early.
+        * ring->ring_backup_entries_to_copy is set to 0 so
+        * the reemit helper will return early as well to
+        * avoid getting stuck in a reemit loop.
+        */
+       if (ring->guilty_fence == guilty_fence) {
+               ring->guilty_fence = NULL;
+               return;
+       }
+       ring->guilty_fence = guilty_fence;
+
        do {
                last_seq++;
                last_seq &= ring->fence_drv.num_fences_mask;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 8f28b3bd70106..9276a3bb69de1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -314,6 +314,7 @@ struct amdgpu_ring {
        uint32_t                *ring_backup;
        unsigned int            ring_backup_entries_to_copy;
        bool                    reemit;
+       struct amdgpu_fence     *guilty_fence;
        unsigned                rptr_offs;
        u64                     rptr_gpu_addr;
        u32                     *rptr_cpu_addr;
-- 
2.54.0

Reply via email to