diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 17 |
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 | /** |