diff options
author | Michel Dänzer <michel.daenzer@amd.com> | 2018-09-20 17:35:40 +0200 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2018-09-26 12:32:14 +0200 |
commit | 0cd2c337d2c02b8ec2bd994d6124b4aaaad10741 (patch) | |
tree | 88d4bab0b14668082a76df76bcc14d21658d2fe2 /src | |
parent | ac5b6f96e97aaf95f4e668b4057006b221cffaec (diff) |
Handle pending scanout update in drmmode_crtc_scanout_free
We have to wait for a pending scanout flip or abort a pending scanout
update, otherwise the corresponding event handler will likely crash
after drmmode_crtc_scanout_free cleaned up the data structures.
Fixes crash after VT switch while dedicated scanout pixmaps are enabled
for any CRTC.
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/amdgpu_kms.c | 2 | ||||
-rw-r--r-- | src/drmmode_display.c | 25 | ||||
-rw-r--r-- | src/drmmode_display.h | 2 |
3 files changed, 18 insertions, 11 deletions
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index 6017c91..06bba55 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -2080,7 +2080,7 @@ void AMDGPULeaveVT_KMS(ScrnInfoPtr pScrn) pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap, None, pAMDGPUEnt); } else { - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); } } } diff --git a/src/drmmode_display.c b/src/drmmode_display.c index cbda8ad..f1e8ce6 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -448,8 +448,17 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, } void -drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc) +drmmode_crtc_scanout_free(xf86CrtcPtr crtc) { + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; + + if (drmmode_crtc->scanout_update_pending) { + amdgpu_drm_wait_pending_flip(crtc); + amdgpu_drm_abort_entry(drmmode_crtc->scanout_update_pending); + drmmode_crtc->scanout_update_pending = 0; + amdgpu_drm_queue_handle_deferred(crtc); + } + drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, &drmmode_crtc->scanout[0]); drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode, @@ -1410,9 +1419,7 @@ done: if (drmmode_crtc->scanout[scanout_id].pixmap && fb != amdgpu_pixmap_get_fb(drmmode_crtc-> scanout[scanout_id].pixmap)) { - amdgpu_drm_abort_entry(drmmode_crtc->scanout_update_pending); - drmmode_crtc->scanout_update_pending = 0; - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); } else if (!drmmode_crtc->tear_free) { drmmode_crtc_scanout_destroy(drmmode, &drmmode_crtc->scanout[1]); @@ -1737,7 +1744,7 @@ static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) } } - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); drmmode_crtc->prime_scanout_pixmap = NULL; if (!ppix) @@ -1752,7 +1759,7 @@ static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1], ppix->drawable.width, ppix->drawable.height)) { - drmmode_crtc_scanout_free(drmmode_crtc); + drmmode_crtc_scanout_free(crtc); return FALSE; } @@ -3345,6 +3352,9 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) if (!info->drmmode_inited) return; + for (c = 0; c < config->num_crtc; c++) + drmmode_crtc_scanout_free(config->crtc[c]); + if (pAMDGPUEnt->fd_wakeup_registered == serverGeneration && !--pAMDGPUEnt->fd_wakeup_ref) { #if HAVE_NOTIFY_FD @@ -3355,9 +3365,6 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode) drm_wakeup_handler, drmmode); #endif } - - for (c = 0; c < config->num_crtc; c++) - drmmode_crtc_scanout_free(config->crtc[c]->driver_private); } static void drmmode_sprite_do_set_cursor(struct amdgpu_device_priv *device_priv, diff --git a/src/drmmode_display.h b/src/drmmode_display.h index c245ae8..3988631 100644 --- a/src/drmmode_display.h +++ b/src/drmmode_display.h @@ -234,7 +234,7 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode, struct drmmode_scanout *scanout); -void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc); +void drmmode_crtc_scanout_free(xf86CrtcPtr crtc); PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc, struct drmmode_scanout *scanout, int width, int height); |