If when we backup the ring contents for reemit before a
ring reset, we skip jobs associated with the bad
context, however, we need to make sure the fences
are reemited as unprocessed submissions may depend on
them.

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

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 334ddd6e48c06..9dfae9532c70e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -116,8 +116,10 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct 
amdgpu_fence *af,
                       &ring->fence_drv.lock,
                       adev->fence_context + ring->idx, seq);
 
+       amdgpu_fence_save_fence_wptr_start(af);
        amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr,
                               seq, flags | AMDGPU_FENCE_FLAG_INT);
+       amdgpu_fence_save_fence_wptr_end(af);
        amdgpu_fence_save_wptr(af);
        pm_runtime_get_noresume(adev_to_drm(adev)->dev);
        ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
@@ -743,10 +745,6 @@ void amdgpu_fence_driver_guilty_force_completion(struct 
amdgpu_fence *af)
                /* if we've already reemitted once then just cancel everything 
*/
                amdgpu_fence_driver_force_completion(af->ring);
                af->ring->ring_backup_entries_to_copy = 0;
-       } else {
-               /* signal the guilty fence */
-               amdgpu_fence_write(ring, (u32)af->base.seqno);
-               amdgpu_fence_process(ring);
        }
 }
 
@@ -755,6 +753,18 @@ void amdgpu_fence_save_wptr(struct amdgpu_fence *af)
        af->wptr = af->ring->wptr;
 }
 
+void amdgpu_fence_save_fence_wptr_start(struct amdgpu_fence *af)
+{
+       af->fence_wptr_start[af->fence_count] = af->ring->wptr;
+}
+
+void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af)
+{
+       af->fence_wptr_end[af->fence_count] = af->ring->wptr;
+       if (af->fence_count < 2)
+               af->fence_count++;
+}
+
 static void amdgpu_ring_backup_unprocessed_command(struct amdgpu_ring *ring,
                                                   u64 start_wptr, u32 end_wptr)
 {
@@ -775,6 +785,7 @@ void amdgpu_ring_backup_unprocessed_commands(struct 
amdgpu_ring *ring,
        struct amdgpu_fence *fence;
        u64 wptr;
        u32 seq, last_seq;
+       int i;
 
        last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
        seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
@@ -796,9 +807,17 @@ void amdgpu_ring_backup_unprocessed_commands(struct 
amdgpu_ring *ring,
                         * just save the content from other contexts.
                         */
                        if (!fence->reemitted &&
-                           (!guilty_fence || (fence->context != 
guilty_fence->context)))
+                           (!guilty_fence || (fence->context != 
guilty_fence->context))) {
                                amdgpu_ring_backup_unprocessed_command(ring, 
wptr,
                                                                       
fence->wptr);
+                       } else if (!fence->reemitted) {
+                               /* always save the fences */
+                               for (i = 0; i < fence->fence_count; i++) {
+                                       
amdgpu_ring_backup_unprocessed_command(ring,
+                                                                              
fence->fence_wptr_start[i],
+                                                                              
fence->fence_wptr_end[i]);
+                               }
+                       }
                        wptr = fence->wptr;
                        fence->reemitted++;
                }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index f93bf83f7f5e4..51b80c18ded9c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -151,12 +151,16 @@ struct amdgpu_fence {
        struct amdgpu_ring              *ring;
        ktime_t                         start_timestamp;
 
-       /* wptr for the fence for resets */
+       /* wptr for the total submission for resets */
        u64                             wptr;
        /* fence context for resets */
        u64                             context;
        /* has this fence been reemitted */
        unsigned int                    reemitted;
+       /* wptrs for the fences for the submission */
+       u64                             fence_wptr_start[2];
+       u64                             fence_wptr_end[2];
+       unsigned int                    fence_count;
 };
 
 extern const struct drm_sched_backend_ops amdgpu_sched_ops;
@@ -165,6 +169,8 @@ void amdgpu_fence_driver_set_error(struct amdgpu_ring 
*ring, int error);
 void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
 void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af);
 void amdgpu_fence_save_wptr(struct amdgpu_fence *af);
+void amdgpu_fence_save_fence_wptr_start(struct amdgpu_fence *af);
+void amdgpu_fence_save_fence_wptr_end(struct amdgpu_fence *af);
 
 int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
 int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
-- 
2.51.1

Reply via email to