aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index d1558768cfb7..0b109aebfec6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -204,16 +204,25 @@ void amdgpu_fence_process(struct amdgpu_ring *ring)
204 if (seq != ring->fence_drv.sync_seq) 204 if (seq != ring->fence_drv.sync_seq)
205 amdgpu_fence_schedule_fallback(ring); 205 amdgpu_fence_schedule_fallback(ring);
206 206
207 while (last_seq != seq) { 207 if (unlikely(seq == last_seq))
208 return;
209
210 last_seq &= drv->num_fences_mask;
211 seq &= drv->num_fences_mask;
212
213 do {
208 struct fence *fence, **ptr; 214 struct fence *fence, **ptr;
209 215
210 ptr = &drv->fences[++last_seq & drv->num_fences_mask]; 216 ++last_seq;
217 last_seq &= drv->num_fences_mask;
218 ptr = &drv->fences[last_seq];
211 219
212 /* There is always exactly one thread signaling this fence slot */ 220 /* There is always exactly one thread signaling this fence slot */
213 fence = rcu_dereference_protected(*ptr, 1); 221 fence = rcu_dereference_protected(*ptr, 1);
214 RCU_INIT_POINTER(*ptr, NULL); 222 RCU_INIT_POINTER(*ptr, NULL);
215 223
216 BUG_ON(!fence); 224 if (!fence)
225 continue;
217 226
218 r = fence_signal(fence); 227 r = fence_signal(fence);
219 if (!r) 228 if (!r)
@@ -222,7 +231,7 @@ void amdgpu_fence_process(struct amdgpu_ring *ring)
222 BUG(); 231 BUG();
223 232
224 fence_put(fence); 233 fence_put(fence);
225 } 234 } while (last_seq != seq);
226} 235}
227 236
228/** 237/**