mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
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. (Ported from amdgpu commit 0cd2c337d2c02b8ec2bd994d6124b4aaaad10741)
This commit is contained in:
@@ -508,8 +508,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) {
|
||||
radeon_drm_wait_pending_flip(crtc);
|
||||
radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending);
|
||||
drmmode_crtc->scanout_update_pending = 0;
|
||||
radeon_drm_queue_handle_deferred(crtc);
|
||||
}
|
||||
|
||||
drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
&drmmode_crtc->scanout[0]);
|
||||
drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
|
||||
@@ -967,9 +976,7 @@ done:
|
||||
if (drmmode_crtc->scanout[scanout_id].pixmap &&
|
||||
fb != radeon_pixmap_get_fb(drmmode_crtc->
|
||||
scanout[scanout_id].pixmap)) {
|
||||
radeon_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]);
|
||||
@@ -1265,7 +1272,7 @@ 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)
|
||||
@@ -1280,7 +1287,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -2770,6 +2777,9 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
|
||||
if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited)
|
||||
return;
|
||||
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
drmmode_crtc_scanout_free(config->crtc[c]);
|
||||
|
||||
if (pRADEONEnt->fd_wakeup_registered == serverGeneration &&
|
||||
!--pRADEONEnt->fd_wakeup_ref) {
|
||||
#if HAVE_NOTIFY_FD
|
||||
@@ -2780,9 +2790,6 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
|
||||
drm_wakeup_handler, pScrn);
|
||||
#endif
|
||||
}
|
||||
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
drmmode_crtc_scanout_free(config->crtc[c]->driver_private);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -215,7 +215,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);
|
||||
|
||||
@@ -2614,7 +2614,7 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
|
||||
pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
|
||||
None, pRADEONEnt);
|
||||
} else {
|
||||
drmmode_crtc_scanout_free(drmmode_crtc);
|
||||
drmmode_crtc_scanout_free(crtc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user