[PATCH xf86-video-ati 1/3] Handle pending scanout update in drmmode_crtc_scanout_free

Michel Dänzer michel at daenzer.net
Wed Oct 24 16:40:17 UTC 2018


From: Michel Dänzer <michel.daenzer at amd.com>

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)

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/drmmode_display.c | 25 ++++++++++++++++---------
 src/drmmode_display.h |  2 +-
 src/radeon_kms.c      |  2 +-
 3 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 8445ef2a7..7493d636e 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -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);
 }
 
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index bc66eda65..bfc130109 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -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);
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index ae69f3353..50c7137c4 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -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);
 			}
 		    }
 		}
-- 
2.19.1



More information about the amd-gfx mailing list