Prevent leak of scratch register on resume from suspend.
Subsystems (2)
PATCH 1/1 Prevent leak of scratch register on resume from suspend.
Cards typically have 5-7 scratch registers; one of these is reserved for rdev->rptr_save_reg. Unfortunately the reservation is done in function r100_cp_init, which is called by all drivers except r600 - and this function is also invoked on resume from suspend. After several resumes, no scratch registers are free and graphics acceleration is disabled.
Dmesg then reports either:
*ERROR* radeon: cp failed to get scratch reg (-22). *ERROR* radeon: cp isn't working(-22). radeon 0000:01:00.0: failed initializing CP (-22).
or:
*ERROR* radeon: failed to get scratch reg (-22). *ERROR* radeon: failed testing IB on GFX ring (-22). *ERROR* ib ring test failed (-22).
The chain of calls on boot for all except r600 is:radeon_init -> ... -> (rXXX_init) -> rXXX_startup -> r100_cp_init
The chain of calls on resume for all except r600 is:rXXX_resume -> rXXX_startup -> r100_cp_init.
R600 correctly allocates rptr_save_reg in r600_init (ie once only, not in resume). However moving the code into the init functions for all drivers means touching 4 drivers. So instead, this patch just adds a test in r100_cp_init to avoid reallocating on resume. As the rdev structure is allocated via kzalloc in radeon_driver_load_kms, and zero is not a valid registerid, zero safely implies not-yet-allocated.
This issue appears to have been introduced in c7eff978 (3.6.0-rcN)
--- drivers/gpu/drm/radeon/r100.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/radeon/r100.c +2 -1
@@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) ring->ready = true;radeon_ttm_set_active_vram_size (rdev, rdev->mc.real_vram_size); -if (radeon_ring_supports_scratch_reg (rdev, ring)) { +if (!ring->rptr_save_reg/* not resuming from suspend */ + &&radeon_ring_supports_scratch_reg (rdev, ring)) { r =radeon_scratch_get (rdev, &ring->rptr_save_reg);if (r) { DRM_ERROR("failed to get scratch reg for rptr save
(%d).\n", r);
Signature · 1 line
1.7.9.5
Thanks! I've added this to my -fixes branch.
Alex
Quoted 59 lines · Simon Kitching
Cards typically have 5-7 scratch registers; one of these is reserved for
rdev->rptr_save_reg. Unfortunately the reservation is done in functionr100_cp_init, which is called by all drivers except r600 - and this function is also invoked on resume from suspend. After several resumes, no scratch registers are free and graphics acceleration is disabled.Dmesg then reports either:
*ERROR* radeon: cp failed to get scratch reg (-22). *ERROR* radeon: cp isn't working(-22). radeon 0000:01:00.0: failed initializing CP (-22).
or:
*ERROR* radeon: failed to get scratch reg (-22). *ERROR* radeon: failed testing IB on GFX ring (-22). *ERROR* ib ring test failed (-22).The chain of calls on boot for all except r600 is:
radeon_init-> ... -> (rXXX_init) ->rXXX_startup->r100_cp_initThe chain of calls on resume for all except r600 is:
rXXX_resume->rXXX_startup->r100_cp_init.R600 correctly allocates
rptr_save_reginr600_init(ie once only, not in resume). However moving the code into the init functions for all drivers means touching 4 drivers. So instead, this patch just adds a test inr100_cp_initto avoid reallocating on resume. As the rdev structure is allocated via kzalloc inradeon_driver_load_kms, and zero is not a valid registerid, zero safely implies not-yet-allocated.This issue appears to have been introduced in
c7eff978(3.6.0-rcN)Signed-off-by Simon Kitching <[email protected]>--- drivers/gpu/drm/radeon/r100.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)drivers/gpu/drm/radeon/r100.c +2
-1@@ -1182,7 +1182,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) ring->ready = true;radeon_ttm_set_active_vram_size (rdev, rdev->mc.real_vram_size); -if (radeon_ring_supports_scratch_reg (rdev, ring)) { +if (!ring->rptr_save_reg/* not resuming from suspend */ + &&radeon_ring_supports_scratch_reg (rdev, ring)) { r =radeon_scratch_get (rdev, &ring->rptr_save_reg);if (r) {DRM_ERROR("failed to get scratch reg for rptr save (%d).\n",
r);
--
1.7.9.5_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel