[PATCH xf86-video-ati] Don't call unreference FB of pixmaps from different screens in LeaveVT

Michel Dänzer michel at daenzer.net
Fri Sep 20 15:40:04 UTC 2019


From: Michel Dänzer <mdaenzer at redhat.com>

FindClientResourcesByType finds pixmaps from all screens, but trying to
process ones from other screens here makes no sense and likely results
in a crash or memory corruption.

Signed-off-by: Michel Dänzer <mdaenzer at redhat.com>
---
 src/radeon_kms.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 777fc14ee..96505334d 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -2602,16 +2602,25 @@ CARD32 cleanup_black_fb(OsTimerPtr timer, CARD32 now, pointer data)
 }
 
 static void
-pixmap_unref_fb(void *value, XID id, void *cdata)
+pixmap_unref_fb(PixmapPtr pixmap)
 {
-    PixmapPtr pixmap = value;
-    RADEONEntPtr pRADEONEnt = cdata;
+    ScrnInfoPtr scrn = xf86ScreenToScrn(pixmap->drawable.pScreen);
     struct drmmode_fb **fb_ptr = radeon_pixmap_get_fb_ptr(pixmap);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
 
     if (fb_ptr)
 	drmmode_fb_reference(pRADEONEnt->fd, fb_ptr, NULL);
 }
 
+static void
+client_pixmap_unref_fb(void *value, XID id, void *pScreen)
+{
+    PixmapPtr pixmap = value;
+
+    if (pixmap->drawable.pScreen == pScreen)
+	pixmap_unref_fb(pixmap);
+}
+
 void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
@@ -2667,11 +2676,9 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
 
 			if (pScrn->is_gpu) {
 			    if (drmmode_crtc->scanout[0].pixmap)
-				pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap,
-						None, pRADEONEnt);
+				pixmap_unref_fb(drmmode_crtc->scanout[0].pixmap);
 			    if (drmmode_crtc->scanout[1].pixmap)
-				pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
-						None, pRADEONEnt);
+				pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap);
 			} else {
 			    drmmode_crtc_scanout_free(crtc);
 			}
@@ -2691,11 +2698,11 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
 		(!clients[i] || clients[i]->clientState != ClientStateRunning))
 		continue;
 
-	    FindClientResourcesByType(clients[i], RT_PIXMAP, pixmap_unref_fb,
-				      pRADEONEnt);
+	    FindClientResourcesByType(clients[i], RT_PIXMAP,
+				      client_pixmap_unref_fb, pScreen);
 	}
 
-	pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen), None, pRADEONEnt);
+	pixmap_unref_fb(pScreen->GetScreenPixmap(pScreen));
     } else {
 	memset(info->front_buffer->bo.radeon->ptr, 0,
 	       pScrn->displayWidth * info->pixel_bytes * pScrn->virtualY);
-- 
2.23.0



More information about the amd-gfx mailing list