From 12938fad234a3924cc9b82080db4f62fe1cf52bb Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 21 Aug 2018 10:45:29 +0200 Subject: drm/amdgpu: cleanup GPU recovery check a bit (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check if we should call the function instead of providing the forced flag. v2: rebase on KFD changes (Alex) Signed-off-by: Christian König Acked-by: Andrey Grodzovsky Reviewed-by: Huang Rui Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 7056925eb386..da36731460b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -701,7 +701,7 @@ static int amdgpu_debugfs_gpu_recover(struct seq_file *m, void *data) struct amdgpu_device *adev = dev->dev_private; seq_printf(m, "gpu recover\n"); - amdgpu_device_gpu_recover(adev, NULL, true); + amdgpu_device_gpu_recover(adev, NULL); return 0; } -- cgit v1.2.3 From 3e14bedc581c3b7b05cd36352d0d47eca0317497 Mon Sep 17 00:00:00 2001 From: Christian König Date: Tue, 18 Sep 2018 10:38:09 +0200 Subject: drm/amdgpu: remove fence fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DC doesn't seem to have a fallback path either. So when interrupts doesn't work any more we are pretty much busted no matter what. Signed-off-by: Christian König Reviewed-by: Chunming Zhou Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 56 ------------------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 - 3 files changed, 58 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index c43bc83c2d29..6cb35e3dab30 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -146,7 +146,6 @@ extern int amdgpu_cik_support; #define AMDGPU_DEFAULT_GTT_SIZE_MB 3072ULL /* 3GB by default */ #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ -#define AMDGPU_FENCE_JIFFIES_TIMEOUT (HZ / 2) /* AMDGPU_IB_POOL_SIZE must be a power of 2 */ #define AMDGPU_IB_POOL_SIZE 16 #define AMDGPU_DEBUGFS_MAX_COMPONENTS 32 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index da36731460b5..176f28777f5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -195,19 +195,6 @@ int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s) return 0; } -/** - * amdgpu_fence_schedule_fallback - schedule fallback check - * - * @ring: pointer to struct amdgpu_ring - * - * Start a timer as fallback to our interrupts. - */ -static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring) -{ - mod_timer(&ring->fence_drv.fallback_timer, - jiffies + AMDGPU_FENCE_JIFFIES_TIMEOUT); -} - /** * amdgpu_fence_process - check for fence activity * @@ -229,9 +216,6 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) } while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq); - if (seq != ring->fence_drv.sync_seq) - amdgpu_fence_schedule_fallback(ring); - if (unlikely(seq == last_seq)) return; @@ -262,21 +246,6 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) } while (last_seq != seq); } -/** - * amdgpu_fence_fallback - fallback for hardware interrupts - * - * @work: delayed work item - * - * Checks for fence activity. - */ -static void amdgpu_fence_fallback(struct timer_list *t) -{ - struct amdgpu_ring *ring = from_timer(ring, t, - fence_drv.fallback_timer); - - amdgpu_fence_process(ring); -} - /** * amdgpu_fence_wait_empty - wait for all fences to signal * @@ -424,8 +393,6 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, atomic_set(&ring->fence_drv.last_seq, 0); ring->fence_drv.initialized = false; - timer_setup(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, 0); - ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1; spin_lock_init(&ring->fence_drv.lock); ring->fence_drv.fences = kcalloc(num_hw_submission * 2, sizeof(void *), @@ -501,7 +468,6 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); drm_sched_fini(&ring->sched); - del_timer_sync(&ring->fence_drv.fallback_timer); for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) dma_fence_put(ring->fence_drv.fences[j]); kfree(ring->fence_drv.fences); @@ -594,27 +560,6 @@ static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f) return (const char *)fence->ring->name; } -/** - * amdgpu_fence_enable_signaling - enable signalling on fence - * @fence: fence - * - * This function is called with fence_queue lock held, and adds a callback - * to fence_queue that checks if this fence is signaled, and if so it - * signals the fence and removes itself. - */ -static bool amdgpu_fence_enable_signaling(struct dma_fence *f) -{ - struct amdgpu_fence *fence = to_amdgpu_fence(f); - struct amdgpu_ring *ring = fence->ring; - - if (!timer_pending(&ring->fence_drv.fallback_timer)) - amdgpu_fence_schedule_fallback(ring); - - DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx); - - return true; -} - /** * amdgpu_fence_free - free up the fence memory * @@ -645,7 +590,6 @@ static void amdgpu_fence_release(struct dma_fence *f) static const struct dma_fence_ops amdgpu_fence_ops = { .get_driver_name = amdgpu_fence_get_driver_name, .get_timeline_name = amdgpu_fence_get_timeline_name, - .enable_signaling = amdgpu_fence_enable_signaling, .release = amdgpu_fence_release, }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 9cc239968e40..44fc665e4577 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -77,7 +77,6 @@ struct amdgpu_fence_driver { bool initialized; struct amdgpu_irq_src *irq_src; unsigned irq_type; - struct timer_list fallback_timer; unsigned num_fences_mask; spinlock_t lock; struct dma_fence **fences; -- cgit v1.2.3 From 8c5e13ec6a2c26d31d0551dc382661dc10823be0 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Fri, 21 Sep 2018 14:48:50 -0400 Subject: 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 Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 56 +++++++++++++++++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 + 3 files changed, 58 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 6cb35e3dab30..c43bc83c2d29 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -146,6 +146,7 @@ extern int amdgpu_cik_support; #define AMDGPU_DEFAULT_GTT_SIZE_MB 3072ULL /* 3GB by default */ #define AMDGPU_WAIT_IDLE_TIMEOUT_IN_MS 3000 #define AMDGPU_MAX_USEC_TIMEOUT 100000 /* 100 ms */ +#define AMDGPU_FENCE_JIFFIES_TIMEOUT (HZ / 2) /* AMDGPU_IB_POOL_SIZE must be a power of 2 */ #define AMDGPU_IB_POOL_SIZE 16 #define AMDGPU_DEBUGFS_MAX_COMPONENTS 32 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 @@ -195,6 +195,19 @@ int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s) return 0; } +/** + * amdgpu_fence_schedule_fallback - schedule fallback check + * + * @ring: pointer to struct amdgpu_ring + * + * Start a timer as fallback to our interrupts. + */ +static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring) +{ + mod_timer(&ring->fence_drv.fallback_timer, + jiffies + AMDGPU_FENCE_JIFFIES_TIMEOUT); +} + /** * amdgpu_fence_process - check for fence activity * @@ -216,6 +229,9 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) } while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq); + if (seq != ring->fence_drv.sync_seq) + amdgpu_fence_schedule_fallback(ring); + if (unlikely(seq == last_seq)) return; @@ -246,6 +262,21 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) } while (last_seq != seq); } +/** + * amdgpu_fence_fallback - fallback for hardware interrupts + * + * @work: delayed work item + * + * Checks for fence activity. + */ +static void amdgpu_fence_fallback(struct timer_list *t) +{ + struct amdgpu_ring *ring = from_timer(ring, t, + fence_drv.fallback_timer); + + amdgpu_fence_process(ring); +} + /** * amdgpu_fence_wait_empty - wait for all fences to signal * @@ -393,6 +424,8 @@ int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, atomic_set(&ring->fence_drv.last_seq, 0); ring->fence_drv.initialized = false; + timer_setup(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, 0); + ring->fence_drv.num_fences_mask = num_hw_submission * 2 - 1; spin_lock_init(&ring->fence_drv.lock); ring->fence_drv.fences = kcalloc(num_hw_submission * 2, sizeof(void *), @@ -468,6 +501,7 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); drm_sched_fini(&ring->sched); + del_timer_sync(&ring->fence_drv.fallback_timer); for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) dma_fence_put(ring->fence_drv.fences[j]); kfree(ring->fence_drv.fences); @@ -560,6 +594,27 @@ static const char *amdgpu_fence_get_timeline_name(struct dma_fence *f) return (const char *)fence->ring->name; } +/** + * amdgpu_fence_enable_signaling - enable signalling on fence + * @fence: fence + * + * This function is called with fence_queue lock held, and adds a callback + * to fence_queue that checks if this fence is signaled, and if so it + * signals the fence and removes itself. + */ +static bool amdgpu_fence_enable_signaling(struct dma_fence *f) +{ + struct amdgpu_fence *fence = to_amdgpu_fence(f); + struct amdgpu_ring *ring = fence->ring; + + if (!timer_pending(&ring->fence_drv.fallback_timer)) + amdgpu_fence_schedule_fallback(ring); + + DMA_FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx); + + return true; +} + /** * amdgpu_fence_free - free up the fence memory * @@ -590,6 +645,7 @@ static void amdgpu_fence_release(struct dma_fence *f) static const struct dma_fence_ops amdgpu_fence_ops = { .get_driver_name = amdgpu_fence_get_driver_name, .get_timeline_name = amdgpu_fence_get_timeline_name, + .enable_signaling = amdgpu_fence_enable_signaling, .release = amdgpu_fence_release, }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 44fc665e4577..9cc239968e40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -77,6 +77,7 @@ struct amdgpu_fence_driver { bool initialized; struct amdgpu_irq_src *irq_src; unsigned irq_type; + struct timer_list fallback_timer; unsigned num_fences_mask; spinlock_t lock; struct dma_fence **fences; -- cgit v1.2.3 From 7bb086cd0bb728613f20c906c26eddda14821377 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Fri, 21 Sep 2018 15:41:52 -0400 Subject: drm/amdgpu: Add warning message for INT SW fallback. Signed-off-by: Andrey Grodzovsky Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index da36731460b5..1ae25835cad1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -274,6 +274,7 @@ static void amdgpu_fence_fallback(struct timer_list *t) struct amdgpu_ring *ring = from_timer(ring, t, fence_drv.fallback_timer); + DRM_INFO("Fallback to SW interrupt on ring %s due to HW interrupt time out", ring->name); amdgpu_fence_process(ring); } -- cgit v1.2.3 From 3547e3cf1976e6ff72098c8f8e7e4a1c3e727e1d Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Mon, 24 Sep 2018 14:10:22 +0200 Subject: drm/amdgpu: Deactivate SW interrupt fallback in amdgpu_fence_process v2 Deactivate SW interrupt fallback when all emited fences are completed. Also switch interrupt SW fallback message from INFO to WARN. v2: shorten the warning message a bit and only re-activate the timer during processing if it was already activated before. (Christian) Signed-off-by: Andrey Grodzovsky Suggested-by: Christian Konig Reviewed-and-Tested-by: Andrey Grodzovsky Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 1ae25835cad1..4e6e9c9654dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -229,7 +229,8 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) } while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq); - if (seq != ring->fence_drv.sync_seq) + if (del_timer(&ring->fence_drv.fallback_timer) && + seq != ring->fence_drv.sync_seq) amdgpu_fence_schedule_fallback(ring); if (unlikely(seq == last_seq)) @@ -274,7 +275,7 @@ static void amdgpu_fence_fallback(struct timer_list *t) struct amdgpu_ring *ring = from_timer(ring, t, fence_drv.fallback_timer); - DRM_INFO("Fallback to SW interrupt on ring %s due to HW interrupt time out", ring->name); + DRM_WARN("Fence fallback timer expired on ring %s\n", ring->name); amdgpu_fence_process(ring); } -- cgit v1.2.3 From 95d7fc4a412aabd3f5b2e1123c3b8faf1a3d8da7 Mon Sep 17 00:00:00 2001 From: Andrey Grodzovsky Date: Tue, 25 Sep 2018 10:24:16 -0400 Subject: drm/amdgpu: Move fence SW fallback warning v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only print the warning if there was actually some fence processed from the SW fallback timer. v2: Add return value to amdgpu_fence_process to let amdgpu_fence_fallback know fences were actually processed and then print the warning. v3: Always return true if seq != last_seq Signed-off-by: Andrey Grodzovsky Reviewed-by: Christian König Acked-off-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 12 ++++++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 4e6e9c9654dd..5448cf27654e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -216,8 +216,10 @@ static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring) * Checks the current fence value and calculates the last * signalled fence value. Wakes the fence queue if the * sequence number has increased. + * + * Returns true if fence was processed */ -void amdgpu_fence_process(struct amdgpu_ring *ring) +bool amdgpu_fence_process(struct amdgpu_ring *ring) { struct amdgpu_fence_driver *drv = &ring->fence_drv; uint32_t seq, last_seq; @@ -234,7 +236,7 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) amdgpu_fence_schedule_fallback(ring); if (unlikely(seq == last_seq)) - return; + return false; last_seq &= drv->num_fences_mask; seq &= drv->num_fences_mask; @@ -261,6 +263,8 @@ void amdgpu_fence_process(struct amdgpu_ring *ring) dma_fence_put(fence); } while (last_seq != seq); + + return true; } /** @@ -275,8 +279,8 @@ static void amdgpu_fence_fallback(struct timer_list *t) struct amdgpu_ring *ring = from_timer(ring, t, fence_drv.fallback_timer); - DRM_WARN("Fence fallback timer expired on ring %s\n", ring->name); - amdgpu_fence_process(ring); + if (amdgpu_fence_process(ring)) + DRM_WARN("Fence fallback timer expired on ring %s\n", ring->name); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h index 9cc239968e40..4caa301ce454 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -97,7 +97,7 @@ void amdgpu_fence_driver_resume(struct amdgpu_device *adev); int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **fence, unsigned flags); int amdgpu_fence_emit_polling(struct amdgpu_ring *ring, uint32_t *s); -void amdgpu_fence_process(struct amdgpu_ring *ring); +bool amdgpu_fence_process(struct amdgpu_ring *ring); int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); signed long amdgpu_fence_wait_polling(struct amdgpu_ring *ring, uint32_t wait_seq, -- cgit v1.2.3