sometimes GPU is switched to other VFs and won't swich back soon, so the kiq reg access will not signal within a short period, instead of returning TMO error we in fact should sleep 1ms and try again later (when not in interrupt context). And since there is retry scheme provided so the MAX_KIQ_REG_WAIT tmo shouldn't set to a long time, set it to 10ms is enough. if gpu already in reset state, don't retry the KIQ reg access otherwise it would always hang because KIQ was already die. Signed-off-by: Monk Liu <Monk.Liu at amd.com> --- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index b832651..7081eb6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -22,7 +22,7 @@ */ #include "amdgpu.h" -#define MAX_KIQ_REG_WAIT 100000000 /* in usecs */ +#define MAX_KIQ_REG_WAIT 10000 /* in usecs, 10ms */ uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev) { @@ -152,9 +152,14 @@ uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg) amdgpu_ring_commit(ring); spin_unlock_irqrestore(&kiq->ring_lock, flags); +retry_read: r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); if (r < 1) { DRM_ERROR("wait for kiq fence error: %ld\n", r); + if (!in_interrupt() && !adev->in_gpu_reset) { + schedule(); + goto retry_read; + } return ~0; } val = adev->wb.wb[adev->virt.reg_val_offs]; @@ -179,9 +184,15 @@ void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v) amdgpu_ring_commit(ring); spin_unlock_irqrestore(&kiq->ring_lock, flags); +retry_write: r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); - if (r < 1) + if (r < 1) { DRM_ERROR("wait for kiq fence error: %ld\n", r); + if (!in_interrupt() && !adev->in_gpu_reset) { + schedule(); + goto retry_write; + } + } } /** -- 2.7.4