1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/drivers/gpu/drm/amd/display/amdgpu_dm
Shirish S 987bf11644 drm/amd/display: Signal hw_done() after waiting for flip_done()
In amdgpu_dm_commit_tail(), wait until flip_done() is signaled before
we signal hw_done().

[Why]

This is to temporarily address a paging error that occurs when a
nonblocking commit contends with another commit, particularly in a
mirrored display configuration where at least 2 CRTCs are updated.
The error occurs in drm_atomic_helper_wait_for_flip_done(), when we
attempt to access the contents of new_crtc_state->commit.

Here's the sequence for a mirrored 2 display setup (irrelevant steps
left out for clarity):

**THREAD 1**                        | **THREAD 2**
                                    |
Initialize atomic state for flip    |
                                    |
Queue worker                        |
                                   ...

                                    | Do work for flip
                                    |
                                    | Signal hw_done() on CRTC 1
                                    | Signal hw_done() on CRTC 2
                                    |
                                    | Wait for flip_done() on CRTC 1

                                <---- **PREEMPTED BY THREAD 1**

Initialize atomic state for cursor  |
update (1)                          |
                                    |
Do cursor update work on both CRTCs |
                                    |
Clear atomic state (2)              |
**DONE**                            |
                                   ...
                                    |
                                    | Wait for flip_done() on CRTC 2
                                    | *ERROR*
                                    |

The issue starts with (1). When the atomic state is initialized, the
current CRTC states are duplicated to be the new_crtc_states, and
referenced to be the old_crtc_states. (The new_crtc_states are to be
filled with update data.)

Some things to note:

* Due to the mirrored configuration, the cursor updates on both CRTCs.

* At this point, the pflip IRQ has already been handled, and flip_done
  signaled on all CRTCs. The cursor commit can therefore continue.

* The old_crtc_states used by the cursor update are the **same states**
  as the new_crtc_states used by the flip worker.

At (2), the old_crtc_state is freed (*), and the cursor commit
completes. We then context switch back to the flip worker, where we
attempt to access the new_crtc_state->commit object. This is
problematic, as this state has already been freed.

(*) Technically, 'state->crtcs[i].state' is freed, which was made to
    reference old_crtc_state in drm_atomic_helper_swap_state()

[How]

By moving hw_done() after wait_for_flip_done(), we're guaranteed that
the new_crtc_state (from the flip worker's perspective) still exists.
This is because any other commit will be blocked, waiting for the
hw_done() signal.

Note that both the i915 and imx drivers have this sequence flipped
already, masking this problem.

Signed-off-by: Shirish S <shirish.s@amd.com>
Signed-off-by: Leo Li <sunpeng.li@amd.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
2018-10-04 11:21:03 -04:00
..
amdgpu_dm.c drm/amd/display: Signal hw_done() after waiting for flip_done() 2018-10-04 11:21:03 -04:00
amdgpu_dm.h drm/amdgpu/display: drop DRM_AMD_DC_FBC kconfig option 2018-06-15 12:20:29 -05:00
amdgpu_dm_color.c drm/amd/display: Implement custom degamma lut on dcn 2018-08-06 14:35:25 -05:00
amdgpu_dm_crc.c drm/amd/display: Guard against null crtc in CRC IRQ 2018-08-13 17:29:44 -05:00
amdgpu_dm_debugfs.c drm/amd/display: dp debugfs allow link rate lane count greater than dp rx reported caps 2018-07-13 14:51:53 -05:00
amdgpu_dm_debugfs.h drm/amd/display: Add front end for dp debugfs files 2018-07-05 16:38:38 -05:00
amdgpu_dm_helpers.c drm/amd/display: Add hook for MST root branch info 2018-07-16 16:11:49 -05:00
amdgpu_dm_irq.c drm/amd/display: Do not program interrupt status on disabled crtc 2018-05-29 13:30:38 -05:00
amdgpu_dm_irq.h drm/amd/display: make amdgpu_dm_irq_handler static 2017-10-17 10:43:04 +10:00
amdgpu_dm_mst_types.c Merge branch 'drm-next-4.19' of git://people.freedesktop.org/~agd5f/linux into drm-next 2018-07-20 14:54:31 +10:00
amdgpu_dm_mst_types.h drm/amd/display: Fix rehook MST display not light back on 2017-12-20 14:46:38 -05:00
amdgpu_dm_pp_smu.c drm/amd/display: Fix bug use wrong pp interface 2018-08-24 11:16:58 -05:00
amdgpu_dm_services.c BackMerge v4.18-rc7 into drm-next 2018-07-30 10:39:22 +10:00
Makefile drm/amd/display: Moving powerplay functions to a separate class 2018-07-05 16:38:41 -05:00