drm/amd/display: Fix secure display lock problems
[Why] Find out few locks problems while doing secure display. They are following few parts: 1. crc_rd_work_lock in amdgpu_dm_crtc_handle_crc_window_irq() should also use spin_lock_irqsave instead of spin_lock_irq. 2. In crc_win_update_set(), crc_rd_work_lock should be grabbed after obtaining lock event_lock. Otherwise, will cause deadlock by conflicting the lock order in amdgpu_dm_crtc_handle_crc_window_irq() 3. flush_work() in crc_win_update_set() is no need and will cause deadlock since amdgpu_dm_crtc_notify_ta_to_read() also tries to grab lock crc_rd_work_lock. [How] Fix above problems. Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Wayne Lin <Wayne.Lin@amd.com> Reviewed-by: Solomon Chiu <Solomon.Chiu@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
4870bd8813
commit
cd95ef0097
|
@ -433,7 +433,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
|||
struct amdgpu_device *adev = NULL;
|
||||
struct crc_rd_work *crc_rd_wrk = NULL;
|
||||
struct crc_params *crc_window = NULL, tmp_window;
|
||||
unsigned long flags;
|
||||
unsigned long flags1, flags2;
|
||||
struct crtc_position position;
|
||||
uint32_t v_blank;
|
||||
uint32_t v_back_porch;
|
||||
|
@ -447,7 +447,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
|||
adev = drm_to_adev(crtc->dev);
|
||||
drm_dev = crtc->dev;
|
||||
|
||||
spin_lock_irqsave(&drm_dev->event_lock, flags);
|
||||
spin_lock_irqsave(&drm_dev->event_lock, flags1);
|
||||
stream_state = acrtc->dm_irq_params.stream;
|
||||
cur_crc_src = acrtc->dm_irq_params.crc_src;
|
||||
timing_out = &stream_state->timing;
|
||||
|
@ -508,10 +508,10 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
|||
if (acrtc->dm_irq_params.crc_window.skip_frame_cnt == 0) {
|
||||
if (adev->dm.crc_rd_wrk) {
|
||||
crc_rd_wrk = adev->dm.crc_rd_wrk;
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
spin_lock_irqsave(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
crc_rd_wrk->phy_inst =
|
||||
stream_state->link->link_enc_hw_inst;
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
spin_unlock_irqrestore(&crc_rd_wrk->crc_rd_work_lock, flags2);
|
||||
schedule_work(&crc_rd_wrk->notify_ta_work);
|
||||
}
|
||||
} else {
|
||||
|
@ -522,7 +522,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc)
|
|||
}
|
||||
|
||||
cleanup:
|
||||
spin_unlock_irqrestore(&drm_dev->event_lock, flags);
|
||||
spin_unlock_irqrestore(&drm_dev->event_lock, flags1);
|
||||
}
|
||||
|
||||
void amdgpu_dm_crtc_secure_display_resume(struct amdgpu_device *adev)
|
||||
|
|
|
@ -2695,14 +2695,12 @@ static int crc_win_update_set(void *data, u64 val)
|
|||
struct crc_rd_work *crc_rd_wrk = adev->dm.crc_rd_wrk;
|
||||
|
||||
if (val) {
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
spin_lock_irq(&adev_to_drm(adev)->event_lock);
|
||||
spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
if (crc_rd_wrk && crc_rd_wrk->crtc) {
|
||||
old_crtc = crc_rd_wrk->crtc;
|
||||
old_acrtc = to_amdgpu_crtc(old_crtc);
|
||||
flush_work(&adev->dm.crc_rd_wrk->notify_ta_work);
|
||||
}
|
||||
|
||||
new_acrtc = to_amdgpu_crtc(new_crtc);
|
||||
|
||||
if (old_crtc && old_crtc != new_crtc) {
|
||||
|
@ -2720,8 +2718,8 @@ static int crc_win_update_set(void *data, u64 val)
|
|||
new_acrtc->dm_irq_params.crc_window.skip_frame_cnt = 0;
|
||||
crc_rd_wrk->crtc = new_crtc;
|
||||
}
|
||||
spin_unlock_irq(&adev_to_drm(adev)->event_lock);
|
||||
spin_unlock_irq(&crc_rd_wrk->crc_rd_work_lock);
|
||||
spin_unlock_irq(&adev_to_drm(adev)->event_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue