aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
diff options
context:
space:
mode:
authorAndrey Grodzovsky <andrey.grodzovsky@amd.com>2018-09-21 14:48:50 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-09-26 22:09:13 -0400
commit8c5e13ec6a2c26d31d0551dc382661dc10823be0 (patch)
tree3a0dfc500ae1fcaa0b696740b523c3e291fd30f2 /drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
parentc95f75f4e86c1c0d867b76f2a134dbeac099cf89 (diff)
Revert "drm/amdgpu: remove fence fallback"
This reverts commit 9b0df0937a852d299fbe42a5939c9a8a4cc83c55. This commit breaks KCQ IB test and S3 on Polaris 11. Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
index 176f28777f5e..da36731460b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -196,6 +196,19 @@ int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s)
196} 196}
197 197
198/** 198/**
199 * amdgpu_fence_schedule_fallback - schedule fallback check
200 *
201 * @ring: pointer to struct amdgpu_ring
202 *
203 * Start a timer as fallback to our interrupts.
204 */
205static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring)
206{
207 mod_timer(&ring->fence_drv.fallback_timer,
208 jiffies + AMDGPU_FENCE_JIFFIES_TIMEOUT);
209}
210
211/**
199 * amdgpu_fence_process - check for fence activity 212 * amdgpu_fence_process - check for fence activity
200 * 213 *
201 * @ring: pointer to struct amdgpu_ring 214 * @ring: pointer to struct amdgpu_ring
@@ -216,6 +229,9 @@ void amdgpu_fence_process(struct amdgpu_ring *ring)
216 229
217 } while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq); 230 } while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq);
218 231
232 if (seq != ring->fence_drv.sync_seq)
233 amdgpu_fence_schedule_fallback(ring);
234
219 if (unlikely(seq == last_seq)) 235 if (unlikely(seq == last_seq))
220 return; 236 return;
221 237
@@ -247,6 +263,21 @@ void amdgpu_fence_process(struct amdgpu_ring *ring)
247} 263}
248 264
249/** 265/**
266 * amdgpu_fence_fallback - fallback for hardware interrupts
267 *
268 * @work: delayed work item
269 *
270 * Checks for fence activity.
271 */
272static void amdgpu_fence_fallback(struct timer_list *t)
273{
274 struct amdgpu_ring *ring = from_timer(ring, t,
275 fence_drv.fallback_timer);
276
277 amdgpu_fence_process(ring);
278}
279
280/**
250 * amdgpu_fence_wait_empty - wait for all fences to signal 281 * amdgpu_fence_wait_empty - wait for all fences to signal
251 * 282 *
252 * @adev: amdgpu device pointer 283 * @adev: amdgpu device pointer
@@ -393,6 +424,8 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring,
393 atomic_set(&ring->fence_drv.last_seq, 0); 424 atomic_set(&ring->fence_drv.last_seq, 0);
394 ring->fence_drv.initialized = false; 425 ring->fence_drv.initialized = false;
395 426
427 timer_setup(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, 0);
428
396 ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1; 429 ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1;
397 spin_lock_init(&ring->fence_drv.lock); 430 spin_lock_init(&ring->fence_drv.lock);
398 ring->fence_drv.fences = kcalloc(num_hw_submission * 2, sizeof(void *), 431 ring->fence_drv.fences = kcalloc(num_hw_submission * 2, sizeof(void *),
@@ -468,6 +501,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev)
468 amdgpu_irq_put(adev, ring->fence_drv.irq_src, 501 amdgpu_irq_put(adev, ring->fence_drv.irq_src,
469 ring->fence_drv.irq_type); 502 ring->fence_drv.irq_type);
470 drm_sched_fini(&ring->sched); 503 drm_sched_fini(&ring->sched);
504 del_timer_sync(&ring->fence_drv.fallback_timer);
471 for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) 505 for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j)
472 dma_fence_put(ring->fence_drv.fences[j]); 506 dma_fence_put(ring->fence_drv.fences[j]);
473 kfree(ring->fence_drv.fences); 507 kfree(ring->fence_drv.fences);
@@ -561,6 +595,27 @@ static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f)
561} 595}
562 596
563/** 597/**
598 * amdgpu_fence_enable_signaling - enable signalling on fence
599 * @fence: fence
600 *
601 * This function is called with fence_queue lock held, and adds a callback
602 * to fence_queue that checks if this fence is signaled, and if so it
603 * signals the fence and removes itself.
604 */
605static bool amdgpu_fence_enable_signaling(struct dma_fence *f)
606{
607 struct amdgpu_fence *fence = to_amdgpu_fence(f);
608 struct amdgpu_ring *ring = fence->ring;
609
610 if (!timer_pending(&ring->fence_drv.fallback_timer))
611 amdgpu_fence_schedule_fallback(ring);
612
613 DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx);
614
615 return true;
616}
617
618/**
564 * amdgpu_fence_free - free up the fence memory 619 * amdgpu_fence_free - free up the fence memory
565 * 620 *
566 * @rcu: RCU callback head 621 * @rcu: RCU callback head
@@ -590,6 +645,7 @@ static void amdgpu_fence_release(struct dma_fence *f)
590static const struct dma_fence_ops amdgpu_fence_ops = { 645static const struct dma_fence_ops amdgpu_fence_ops = {
591 .get_driver_name = amdgpu_fence_get_driver_name, 646 .get_driver_name = amdgpu_fence_get_driver_name,
592 .get_timeline_name = amdgpu_fence_get_timeline_name, 647 .get_timeline_name = amdgpu_fence_get_timeline_name,
648 .enable_signaling = amdgpu_fence_enable_signaling,
593 .release = amdgpu_fence_release, 649 .release = amdgpu_fence_release,
594}; 650};
595 651