From: Christian König christian.koenig@amd.com
We must mask out the overflow bit as well, otherwise the wptr will never match the rptr again and the interrupt handler will loop forever.
Signed-off-by: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/cik.c | 1 + drivers/gpu/drm/radeon/evergreen.c | 1 + drivers/gpu/drm/radeon/r600.c | 1 + drivers/gpu/drm/radeon/si.c | 1 + 4 files changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 0b24711..cc1f02f 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -7376,6 +7376,7 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp); + wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask); } diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 250bac3..15e4f28 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -4756,6 +4756,7 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp); + wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask); } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c66952d..3c69f58 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -3795,6 +3795,7 @@ static u32 r600_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp); + wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask); } diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index eba0225..9e854fd 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6103,6 +6103,7 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp); + wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask); }
On 23.07.2014 16:47, Christian König wrote:
From: Christian König christian.koenig@amd.com
We must mask out the overflow bit as well, otherwise the wptr will never match the rptr again and the interrupt handler will loop forever.
Signed-off-by: Christian König christian.koenig@amd.com
Reviewed-by: Michel Dänzer michel.daenzer@amd.com
Cc: stable@vger.kernel.org
Not sure this is justified though. Were you able to reproduce the problem and verify the fix?
Am 23.07.2014 11:07, schrieb Michel Dänzer:
On 23.07.2014 16:47, Christian König wrote:
From: Christian König christian.koenig@amd.com
We must mask out the overflow bit as well, otherwise the wptr will never match the rptr again and the interrupt handler will loop forever.
Signed-off-by: Christian König christian.koenig@amd.com
Reviewed-by: Michel Dänzer michel.daenzer@amd.com
Cc: stable@vger.kernel.org
Not sure this is justified though. Were you able to reproduce the problem and verify the fix?
Not yet, reproducing ring buffer overflows aren't easy to do. But I've had that multiple times with CIK and userptr support work and I can try if I can reproduce it once more.
From reading the code it looks like a rather fundamental problem to me and because of this I've added the stable Cc.
Christian.
On Wed, Jul 23, 2014 at 3:47 AM, Christian König deathsimple@vodafone.de wrote:
From: Christian König christian.koenig@amd.com
We must mask out the overflow bit as well, otherwise the wptr will never match the rptr again and the interrupt handler will loop forever.
Signed-off-by: Christian König christian.koenig@amd.com Cc: stable@vger.kernel.org
Applied to my 3.16 tree. Thanks!
Alex
drivers/gpu/drm/radeon/cik.c | 1 + drivers/gpu/drm/radeon/evergreen.c | 1 + drivers/gpu/drm/radeon/r600.c | 1 + drivers/gpu/drm/radeon/si.c | 1 + 4 files changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 0b24711..cc1f02f 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -7376,6 +7376,7 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp);
wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask);
} diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 250bac3..15e4f28 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -4756,6 +4756,7 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp);
wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask);
} diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index c66952d..3c69f58 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -3795,6 +3795,7 @@ static u32 r600_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp);
wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask);
} diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index eba0225..9e854fd 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6103,6 +6103,7 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev) tmp = RREG32(IH_RB_CNTL); tmp |= IH_WPTR_OVERFLOW_CLEAR; WREG32(IH_RB_CNTL, tmp);
wptr &= ~RB_OVERFLOW; } return (wptr & rdev->ih.ptr_mask);
}
1.9.1
dri-devel@lists.freedesktop.org