xf86-video-ati: Branch 'master' - 2 commits

Michel Dänzer daenzer at kemper.freedesktop.org
Fri Jun 30 08:43:03 UTC 2017


 src/drmmode_display.c |    8 ++++++--
 src/drmmode_display.h |   29 ++++++++++++++++++-----------
 src/radeon_kms.c      |    8 ++++----
 3 files changed, 28 insertions(+), 17 deletions(-)

New commits:
commit 19626bce4e5e31c863eedb503ea3884ac3f60bea
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Jun 27 18:32:28 2017 +0900

    Improve drmmode_fb_reference debugging code
    
    If a reference count is <= 0, call FatalError with the call location
    (in case it doesn't get resolved in the backtrace printed by
    FatalError).
    
    (Ported from amdgpu commit 1b6ff5fd9933c00ec1ec90dfc62e0b531927749b)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index db68054a..dde27a00 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -141,29 +141,36 @@ enum drmmode_flip_sync {
 
 
 static inline void
-drmmode_fb_reference(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new)
+drmmode_fb_reference_loc(int drm_fd, struct drmmode_fb **old, struct drmmode_fb *new,
+			 const char *caller, unsigned line)
 {
     if (new) {
-	if (new->refcnt <= 0)
-	    ErrorF("New FB's refcnt was %d in %s\n", new->refcnt, __func__);
-	else
-	    new->refcnt++;
+	if (new->refcnt <= 0) {
+	    FatalError("New FB's refcnt was %d at %s:%u",
+		       new->refcnt, caller, line);
+	}
+
+	new->refcnt++;
     }
 
     if (*old) {
 	if ((*old)->refcnt <= 0) {
-	    ErrorF("Old FB's refcnt was %d in %s\n", (*old)->refcnt, __func__);
-	} else {
-	    if (--(*old)->refcnt == 0) {
-		drmModeRmFB(drm_fd, (*old)->handle);
-		free(*old);
-	    }
+	    FatalError("Old FB's refcnt was %d at %s:%u",
+		       (*old)->refcnt, caller, line);
+	}
+
+	if (--(*old)->refcnt == 0) {
+	    drmModeRmFB(drm_fd, (*old)->handle);
+	    free(*old);
 	}
     }
 
     *old = new;
 }
 
+#define drmmode_fb_reference(fd, old, new) \
+    drmmode_fb_reference_loc(fd, old, new, __func__, __LINE__)
+
 
 extern int drmmode_page_flip_target_absolute(RADEONEntPtr pRADEONEnt,
 					     drmmode_crtc_private_ptr drmmode_crtc,
commit bc46ffdf71ab3dfa0f95572529e818f2b619d380
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Jun 27 18:19:31 2017 +0900

    Increase reference count of FB assigned to drmmode_crtc->flip_pending
    
    Otherwise, it could happen that we destroy the FB before the flip
    completes, resulting in use-after-free and most likely a crash.
    
    (Ported from amdgpu commit af7221e1c4d2dbdfd488eb0976a835584ea8441c)
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 9deaa575..dd394ec1 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2369,8 +2369,11 @@ void
 drmmode_clear_pending_flip(xf86CrtcPtr crtc)
 {
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	ScrnInfoPtr scrn = crtc->scrn;
+	RADEONEntPtr pRADEONEnt = RADEONEntPriv(scrn);
 
-	drmmode_crtc->flip_pending = NULL;
+	drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
+			     NULL);
 
 	if (!crtc->enabled ||
 	    (drmmode_crtc->pending_dpms_mode != DPMSModeOn &&
@@ -3030,7 +3033,8 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr client,
 				goto flip_error;
 		}
 
-		drmmode_crtc->flip_pending = fb;
+		drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
+				     fb);
 		drm_queue_seq = 0;
 	}
 
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 5637e7f8..691fcdf5 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -815,8 +815,8 @@ radeon_prime_scanout_flip(PixmapDirtyUpdatePtr ent)
 	return;
     }
 
-    drmmode_crtc->flip_pending =
-	radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap);
+    drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
+			  radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap));
     if (!drmmode_crtc->flip_pending) {
 	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
 		   "Failed to get FB for PRIME flip.\n");
@@ -1110,8 +1110,8 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
 	return;
     }
 
-    drmmode_crtc->flip_pending =
-	radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap);
+    drmmode_fb_reference(pRADEONEnt->fd, &drmmode_crtc->flip_pending,
+			  radeon_pixmap_get_fb(drmmode_crtc->scanout[scanout_id].pixmap));
     if (!drmmode_crtc->flip_pending) {
 	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
 		   "Failed to get FB for scanout flip.\n");


More information about the xorg-commit mailing list