]> git.hungrycats.org Git - linux/commitdiff
drm/amdgpu/fence: add helper to extract the guilty fence
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 12 May 2026 14:23:02 +0000 (10:23 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 17 Jun 2026 19:51:33 +0000 (15:51 -0400)
Add a helper to extract the first amdgpu_fence which has
not yet signalled and is thus guilty or at least collateral
damage.

Reviewed-by: Jesse Zhang <jesse.zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h

index a7a6db0bc6940a1f0d7ea0ca8e4defa80280b917..733e9b668ed8fad45131a765e12c3544996d13b6 100644 (file)
@@ -831,6 +831,37 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
        } while (last_seq != seq);
 }
 
+struct amdgpu_fence *
+amdgpu_ring_find_guilty_fence(struct amdgpu_ring *ring)
+{
+       struct dma_fence *unprocessed;
+       struct dma_fence __rcu **ptr;
+       struct amdgpu_fence *fence;
+       u32 seq, last_seq;
+
+       last_seq = amdgpu_fence_read(ring) & ring->fence_drv.num_fences_mask;
+       seq = ring->fence_drv.sync_seq & ring->fence_drv.num_fences_mask;
+       ring->ring_backup_entries_to_copy = 0;
+
+       do {
+               last_seq++;
+               last_seq &= ring->fence_drv.num_fences_mask;
+
+               ptr = &ring->fence_drv.fences[last_seq];
+               rcu_read_lock();
+               unprocessed = rcu_dereference(*ptr);
+
+               if (unprocessed && !dma_fence_is_signaled(unprocessed)) {
+                       fence = container_of(unprocessed, struct amdgpu_fence, base);
+                       rcu_read_unlock();
+                       return fence;
+               }
+               rcu_read_unlock();
+       } while (last_seq != seq);
+
+       return NULL;
+}
+
 /*
  * Common fence implementation
  */
index 9276a3bb69de1e0a686ad41b11f1725defe82758..71cd9bb12f75b69e188a8430dcfc2864343d5392 100644 (file)
@@ -589,6 +589,8 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev);
 bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring);
 void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
                                             struct amdgpu_fence *guilty_fence);
+struct amdgpu_fence *
+amdgpu_ring_find_guilty_fence(struct amdgpu_ring *ring);
 void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring,
                                    struct amdgpu_fence *guilty_fence);
 int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring,