aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display
diff options
context:
space:
mode:
authorDarren Salt <devspam@moreofthesa.me.uk>2017-09-12 12:10:25 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 18:17:07 -0400
commit9635b75436e5f536831c810c715f3ae24a5bbbae (patch)
treecdf706671e13f79a9e1d7ac0eecfe4cb65e5131c /drivers/gpu/drm/amd/display
parent62f555377f972c206c69c6acc93d91f2baec9a26 (diff)
drm/amd/display: Don't leak dc_stream_state.
Noticed while playing “Valley”, which was causing some 8MB of leakage per second. kmemleak listed many entries looking like this: unreferenced object 0xffff8802c2951800 (size 1024): comm "Xorg", pid 2982, jiffies 4297410155 (age 392.787s) hex dump (first 32 bytes): 00 50 f9 0c 04 88 ff ff 98 08 00 00 00 00 00 00 .P.............. 80 07 00 00 00 00 00 00 58 00 00 00 2c 00 00 00 ........X...,... backtrace: [<ffffffff810cd4c3>] create_object+0x13c/0x261 [<ffffffff815abdc2>] kmemleak_alloc+0x20/0x3c [<ffffffff810cad1d>] slab_post_alloc_hook+0x42/0x52 [<ffffffff810cb8e0>] kmem_cache_alloc+0x67/0x76 [<ffffffff813bbb54>] dc_create_stream_for_sink+0x24/0x1cf [<ffffffff81373aaa>] create_stream_for_sink+0x6f/0x295 [<ffffffff81373dc2>] dm_update_crtcs_state+0xa6/0x268 [<ffffffff8137401e>] amdgpu_dm_atomic_check+0x9a/0x314 [<ffffffff812ac3dd>] drm_atomic_check_only+0x17a/0x42d [<ffffffff812ac6a3>] drm_atomic_commit+0x13/0x4b [<ffffffff812ad1a5>] drm_atomic_connector_commit_dpms+0xcb/0xe8 [<ffffffff812b1238>] drm_mode_obj_set_property_ioctl+0xe6/0x1e3 [<ffffffff812b027b>] drm_mode_connector_property_set_ioctl+0x2b/0x2d [<ffffffff8129f427>] drm_ioctl_kernel+0x64/0x9d [<ffffffff8129f6a2>] drm_ioctl+0x230/0x316 [<ffffffff812ca4d3>] amdgpu_drm_ioctl+0x4b/0x7d v2: also handle break statements. Signed-off-by: Darren Salt <devspam@moreofthesa.me.uk> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 193a634f46e6..4f1e31cd4cbe 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4357,6 +4357,7 @@ static int dm_update_crtcs_state(
4357 int i; 4357 int i;
4358 struct dm_crtc_state *old_acrtc_state, *new_acrtc_state; 4358 struct dm_crtc_state *old_acrtc_state, *new_acrtc_state;
4359 struct dm_atomic_state *dm_state = to_dm_atomic_state(state); 4359 struct dm_atomic_state *dm_state = to_dm_atomic_state(state);
4360 struct dc_stream_state *new_stream;
4360 int ret = 0; 4361 int ret = 0;
4361 4362
4362 /*TODO Move this code into dm_crtc_atomic_check once we get rid of dc_validation_set */ 4363 /*TODO Move this code into dm_crtc_atomic_check once we get rid of dc_validation_set */
@@ -4364,10 +4365,11 @@ static int dm_update_crtcs_state(
4364 for_each_crtc_in_state(state, crtc, crtc_state, i) { 4365 for_each_crtc_in_state(state, crtc, crtc_state, i) {
4365 struct amdgpu_crtc *acrtc = NULL; 4366 struct amdgpu_crtc *acrtc = NULL;
4366 struct amdgpu_connector *aconnector = NULL; 4367 struct amdgpu_connector *aconnector = NULL;
4367 struct dc_stream_state *new_stream = NULL;
4368 struct drm_connector_state *conn_state = NULL; 4368 struct drm_connector_state *conn_state = NULL;
4369 struct dm_connector_state *dm_conn_state = NULL; 4369 struct dm_connector_state *dm_conn_state = NULL;
4370 4370
4371 new_stream = NULL;
4372
4371 old_acrtc_state = to_dm_crtc_state(crtc->state); 4373 old_acrtc_state = to_dm_crtc_state(crtc->state);
4372 new_acrtc_state = to_dm_crtc_state(crtc_state); 4374 new_acrtc_state = to_dm_crtc_state(crtc_state);
4373 acrtc = to_amdgpu_crtc(crtc); 4375 acrtc = to_amdgpu_crtc(crtc);
@@ -4415,7 +4417,7 @@ static int dm_update_crtcs_state(
4415 4417
4416 4418
4417 if (!drm_atomic_crtc_needs_modeset(crtc_state)) 4419 if (!drm_atomic_crtc_needs_modeset(crtc_state))
4418 continue; 4420 goto next_crtc;
4419 4421
4420 DRM_DEBUG_KMS( 4422 DRM_DEBUG_KMS(
4421 "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, " 4423 "amdgpu_crtc id:%d crtc_state_flags: enable:%d, active:%d, "
@@ -4433,7 +4435,7 @@ static int dm_update_crtcs_state(
4433 if (!enable) { 4435 if (!enable) {
4434 4436
4435 if (!old_acrtc_state->stream) 4437 if (!old_acrtc_state->stream)
4436 continue; 4438 goto next_crtc;
4437 4439
4438 DRM_DEBUG_KMS("Disabling DRM crtc: %d\n", 4440 DRM_DEBUG_KMS("Disabling DRM crtc: %d\n",
4439 crtc->base.id); 4441 crtc->base.id);
@@ -4444,7 +4446,7 @@ static int dm_update_crtcs_state(
4444 dm_state->context, 4446 dm_state->context,
4445 old_acrtc_state->stream)) { 4447 old_acrtc_state->stream)) {
4446 ret = -EINVAL; 4448 ret = -EINVAL;
4447 break; 4449 goto fail;
4448 } 4450 }
4449 4451
4450 dc_stream_release(old_acrtc_state->stream); 4452 dc_stream_release(old_acrtc_state->stream);
@@ -4455,7 +4457,7 @@ static int dm_update_crtcs_state(
4455 } else {/* Add stream for any updated/enabled CRTC */ 4457 } else {/* Add stream for any updated/enabled CRTC */
4456 4458
4457 if (modereset_required(crtc_state)) 4459 if (modereset_required(crtc_state))
4458 continue; 4460 goto next_crtc;
4459 4461
4460 if (modeset_required(crtc_state, new_stream, 4462 if (modeset_required(crtc_state, new_stream,
4461 old_acrtc_state->stream)) { 4463 old_acrtc_state->stream)) {
@@ -4473,19 +4475,25 @@ static int dm_update_crtcs_state(
4473 dm_state->context, 4475 dm_state->context,
4474 new_acrtc_state->stream)) { 4476 new_acrtc_state->stream)) {
4475 ret = -EINVAL; 4477 ret = -EINVAL;
4476 break; 4478 goto fail;
4477 } 4479 }
4478 4480
4479 *lock_and_validation_needed = true; 4481 *lock_and_validation_needed = true;
4480 } 4482 }
4481 } 4483 }
4482 4484
4485next_crtc:
4483 /* Release extra reference */ 4486 /* Release extra reference */
4484 if (new_stream) 4487 if (new_stream)
4485 dc_stream_release(new_stream); 4488 dc_stream_release(new_stream);
4486 } 4489 }
4487 4490
4488 return ret; 4491 return ret;
4492
4493fail:
4494 if (new_stream)
4495 dc_stream_release(new_stream);
4496 return ret;
4489} 4497}
4490 4498
4491static int dm_update_planes_state( 4499static int dm_update_planes_state(