[PATCH 38/73] drm/amd/display: Fix warnings on S3 resume
Andrey Grodzovsky
Andrey.Grodzovsky at amd.com
Tue Nov 14 16:03:17 UTC 2017
On 11/14/2017 11:00 AM, Leo Li wrote:
>
>
> On 2017-11-10 01:40 PM, Andrey Grodzovsky wrote:
>>
>>
>> On 11/10/2017 01:38 PM, Andrey Grodzovsky wrote:
>>>
>>>
>>> On 11/09/2017 03:05 PM, Harry Wentland wrote:
>>>> From: "Leo (Sunpeng) Li" <sunpeng.li at amd.com>
>>>>
>>>> This is a followup to the following revert:
>>>>
>>>> Rex Zhu Revert "drm/amd/display: Match actual state during S3
>>>> resume."
>>>>
>>>> Three things needed to be addressed:
>>>>
>>>> 1. Potential memory leak on dc_state creation in atomic_check during
>>>> s3 resume
>>>> 2. Warnings are now seen in dmesg during S3 resume
>>>> 3. Since dc_state is now created in atomic_check, what the reverted
>>>> patch was addressing needs to be reevaluated.
>>>>
>>>> This change addresses the above:
>>>>
>>>> 1. Since the suspend procedure calls drm_atomic_state_clear, our hook
>>>> for releasing the dc_state is called. This frees it before
>>>> atomic_check creates it during resume. The leak does not occur.
>>>>
>>>> 2. The dc_crtc/plane_state references kept by the atomic states
>>>> need to
>>>> be released before calling atomic_check, which warns if they are
>>>> non-null. This is because atomic_check is responsible for creating
>>>> the dc_*_states. This is a special case for S3 resume, since the
>>>> atomic state duplication that occurs during suspend also copies a
>>>> reference to the dc_*_states.
>>>>
>>>> 3. See 2. comments are also updated to reflect this.
>>>>
>>>> Change-Id: I6e342bf8134f0e5dc32888a8d894c2cd20d28296
>>>> Signed-off-by: Leo (Sunpeng) Li <sunpeng.li at amd.com>
>>>> Reviewed-by: Harry Wentland <Harry.Wentland at amd.com>
>>>> ---
>>>> drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28
>>>> +++++++++++++++++++++++
>>>> 1 file changed, 28 insertions(+)
>>>>
>>>> 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 1c7f22146bc9..bdef1ed0dfac 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
>>>> @@ -643,6 +643,11 @@ int amdgpu_dm_display_resume(struct
>>>> amdgpu_device *adev)
>>>> struct drm_connector *connector;
>>>> struct drm_crtc *crtc;
>>>> struct drm_crtc_state *new_crtc_state;
>>>> + struct dm_crtc_state *dm_new_crtc_state;
>>>> + struct drm_plane *plane;
>>>> + struct drm_plane_state *new_plane_state;
>>>> + struct dm_plane_state *dm_new_plane_state;
>>>> +
>>>> int ret = 0;
>>>> int i;
>>>> @@ -685,6 +690,29 @@ int amdgpu_dm_display_resume(struct
>>>> amdgpu_device *adev)
>>>> for_each_new_crtc_in_state(adev->dm.cached_state, crtc,
>>>> new_crtc_state, i)
>>>> new_crtc_state->active_changed = true;
>>>> + /*
>>>> + * atomic_check is expected to create the dc states. We need
>>>> to release
>>>> + * them here, since they were duplicated as part of the suspend
>>>> + * procedure.
>>>> + */
>>>> + for_each_new_crtc_in_state(adev->dm.cached_state, crtc,
>>>> new_crtc_state, i) {
>>>> + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
>>>> + if (dm_new_crtc_state->stream) {
>>>> + WARN_ON(kref_read(&dm_new_crtc_state->stream->refcount) > 1);
>>>> + dc_stream_release(dm_new_crtc_state->stream);
>>>> + dm_new_crtc_state->stream = NULL;
>>>> + }
>>>> + }
>>>> +
>>>> + for_each_new_plane_in_state(adev->dm.cached_state, plane,
>>>> new_plane_state, i) {
>>>> + dm_new_plane_state = to_dm_plane_state(new_plane_state);
>>>> + if (dm_new_plane_state->dc_state) {
>>>> + WARN_ON(kref_read(&dm_new_plane_state->dc_state->refcount) > 1);
>>>> + dc_plane_state_release(dm_new_plane_state->dc_state);
>>>> + dm_new_plane_state->dc_state = NULL;
>>>> + }
>>>> + }
>>>
>>> I guess the warnings you are referring to are in
>>> dm_update_crtcs_state and dm_update_planes_state,
>>> but I don't understand why you need to explicitly release them in
>>> amdgpu_dm_resume, any changed
>>> plane/crtc states will be removed during atomic check anyway and
>>> only after that new one will be added,
>>> I find strange that this doesn't work.
>>>
>>> P.S I tried to reproduce this to see the warnings with latest
>>> amd-staging-drm-next (776fb8c)on CZ but the system becomes
>>> unimpressive after going to suspend, might wanna check this on your
>>> side.
>>
>> UNRESPONSIVE (it's unimpressive in any case :) )
>>
>> Andrey
>>
>
> It's just a special case for s3 resume. The suspend helper first
> duplicates the existing atomic state (which in turn, duplicates
> references to dc states), then calls the disable_all helper. This
> means that during resume, the old state will have everything disabled,
> while the new state is the duplicated state that we're trying to restore.
>
> Our atomic check isn't very happy with this. From it's perspective,
> we're clearly trying to enable a CRTC. It doesn't expect the new
> drm_*_states to have associated dc_*_states yet. This is why the
> releases are necessary within amdgpu_dm_resume; to make things
> consistent for atomic_check.
>
> Leo
I see, this change Reviewed-by: Andrey Grodzovsky
<andrey.grodzovsky at amd.com>
Thanks,
Andrey
>
>>>
>>> Thanks,
>>> Andrey
>>>
>>>> +
>>>> ret = drm_atomic_helper_resume(ddev, adev->dm.cached_state);
>>>> drm_atomic_state_put(adev->dm.cached_state);
>>>
>>> _______________________________________________
>>> amd-gfx mailing list
>>> amd-gfx at lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>>
More information about the amd-gfx
mailing list