Skip to content

Commit

Permalink
drm/amdgpu: Fix dead lock issue for vblank
Browse files Browse the repository at this point in the history
Always start vblank timer, but only calls vblank function
when vblank is enabled.

This is used to fix the dead lock issue.
When drm_crtc_vblank_off want to disable vblank,
it first get event_lock, and then call hrtimer_cancel,
but hrtimer_cancel want to wait timer handler function finished.
Timer handler also want to aquire event_lock in drm_handle_vblank.

Signed-off-by: Emily.Deng <Emily.Deng@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
  • Loading branch information
Emily.Deng authored and Alex Deucher committed Sep 22, 2020
1 parent 9de9a54 commit 36499e4
Showing 1 changed file with 17 additions and 18 deletions.
35 changes: 17 additions & 18 deletions drivers/gpu/drm/amd/amdgpu/dce_virtual.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ static void dce_virtual_set_display_funcs(struct amdgpu_device *adev);
static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev);
static int dce_virtual_connector_encoder_init(struct amdgpu_device *adev,
int index);
static int dce_virtual_pageflip(struct amdgpu_device *adev,
unsigned crtc_id);
static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vblank_timer);
static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
int crtc,
enum amdgpu_interrupt_state state);
Expand Down Expand Up @@ -247,6 +250,11 @@ static int dce_virtual_crtc_init(struct amdgpu_device *adev, int index)
amdgpu_crtc->vsync_timer_enabled = AMDGPU_IRQ_STATE_DISABLE;
drm_crtc_helper_add(&amdgpu_crtc->base, &dce_virtual_crtc_helper_funcs);

hrtimer_init(&amdgpu_crtc->vblank_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hrtimer_set_expires(&amdgpu_crtc->vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD);
amdgpu_crtc->vblank_timer.function = dce_virtual_vblank_timer_handle;
hrtimer_start(&amdgpu_crtc->vblank_timer,
DCE_VIRTUAL_VBLANK_PERIOD, HRTIMER_MODE_REL);
return 0;
}

Expand Down Expand Up @@ -476,7 +484,7 @@ static int dce_virtual_hw_fini(void *handle)

for (i = 0; i<adev->mode_info.num_crtc; i++)
if (adev->mode_info.crtcs[i])
dce_virtual_set_crtc_vblank_interrupt_state(adev, i, AMDGPU_IRQ_STATE_DISABLE);
hrtimer_cancel(&adev->mode_info.crtcs[i]->vblank_timer);

return 0;
}
Expand Down Expand Up @@ -698,9 +706,15 @@ static enum hrtimer_restart dce_virtual_vblank_timer_handle(struct hrtimer *vbla
struct amdgpu_crtc, vblank_timer);
struct drm_device *ddev = amdgpu_crtc->base.dev;
struct amdgpu_device *adev = drm_to_adev(ddev);
struct amdgpu_irq_src *source = adev->irq.client[AMDGPU_IRQ_CLIENTID_LEGACY].sources
[VISLANDS30_IV_SRCID_SMU_DISP_TIMER2_TRIGGER];
int irq_type = amdgpu_display_crtc_idx_to_irq_type(adev,
amdgpu_crtc->crtc_id);

drm_handle_vblank(ddev, amdgpu_crtc->crtc_id);
dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id);
if (amdgpu_irq_enabled(adev, source, irq_type)) {
drm_handle_vblank(ddev, amdgpu_crtc->crtc_id);
dce_virtual_pageflip(adev, amdgpu_crtc->crtc_id);
}
hrtimer_start(vblank_timer, DCE_VIRTUAL_VBLANK_PERIOD,
HRTIMER_MODE_REL);

Expand All @@ -716,21 +730,6 @@ static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *ad
return;
}

if (state && !adev->mode_info.crtcs[crtc]->vsync_timer_enabled) {
DRM_DEBUG("Enable software vsync timer\n");
hrtimer_init(&adev->mode_info.crtcs[crtc]->vblank_timer,
CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hrtimer_set_expires(&adev->mode_info.crtcs[crtc]->vblank_timer,
DCE_VIRTUAL_VBLANK_PERIOD);
adev->mode_info.crtcs[crtc]->vblank_timer.function =
dce_virtual_vblank_timer_handle;
hrtimer_start(&adev->mode_info.crtcs[crtc]->vblank_timer,
DCE_VIRTUAL_VBLANK_PERIOD, HRTIMER_MODE_REL);
} else if (!state && adev->mode_info.crtcs[crtc]->vsync_timer_enabled) {
DRM_DEBUG("Disable software vsync timer\n");
hrtimer_cancel(&adev->mode_info.crtcs[crtc]->vblank_timer);
}

adev->mode_info.crtcs[crtc]->vsync_timer_enabled = state;
DRM_DEBUG("[FM]set crtc %d vblank interrupt state %d\n", crtc, state);
}
Expand Down

0 comments on commit 36499e4

Please sign in to comment.