xf86-video-ati: Branch 'master'

Maarten Lankhorst mlankhorst at kemper.freedesktop.org
Thu Mar 21 02:34:48 PDT 2013


 src/drmmode_display.c |   16 ++++++++++++----
 src/radeon.h          |    1 +
 src/radeon_kms.c      |   12 +++++++++++-
 src/radeon_probe.h    |    2 ++
 4 files changed, 26 insertions(+), 5 deletions(-)

New commits:
commit 1643b8cd2dc53ed36916e11003590c7037b4ddd6
Author: Maarten Lankhorst <maarten.lankhorst at canonical.com>
Date:   Thu Mar 21 10:33:19 2013 +0100

    radeon: add refcounts to fix up zaphod open/close.
    
    Oops, turns out my previous commits were buggy.
    Adding proper refcounts will handle this correctly.
    
    Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index d09c69c..87ab268 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1575,13 +1575,18 @@ void drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 	RADEONInfoPtr info = RADEONPTR(pScrn);
 
-	if (pRADEONEnt->fd_wakeup_registered != serverGeneration &&
-	    info->dri2.pKernelDRMVersion->version_minor >= 4) {
+	if (info->dri2.pKernelDRMVersion->version_minor < 4)
+		return;
+
+	info->drmmode_inited = TRUE;
+	if (pRADEONEnt->fd_wakeup_registered != serverGeneration) {
 		AddGeneralSocket(drmmode->fd);
 		RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
 				drm_wakeup_handler, drmmode);
 		pRADEONEnt->fd_wakeup_registered = serverGeneration;
-	}
+		pRADEONEnt->fd_wakeup_ref = 1;
+	} else
+		pRADEONEnt->fd_wakeup_ref++;
 }
 
 void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
@@ -1589,8 +1594,11 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 	RADEONInfoPtr info = RADEONPTR(pScrn);
 
+	if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited)
+		return;
+
 	if (pRADEONEnt->fd_wakeup_registered == serverGeneration &&
-	    info->dri2.pKernelDRMVersion->version_minor >= 4) {
+	    !--pRADEONEnt->fd_wakeup_ref) {
 		RemoveGeneralSocket(drmmode->fd);
 		RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
 				drm_wakeup_handler, drmmode);
diff --git a/src/radeon.h b/src/radeon.h
index f986347..1cbeef6 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -453,6 +453,7 @@ typedef struct {
     uint64_t vram_size;
     uint64_t gart_size;
     drmmode_rec drmmode;
+    Bool drmmode_inited;
     /* r6xx+ tile config */
     Bool have_tiling_info;
     uint32_t tile_config;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index f997d8a..763acd0 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -555,6 +555,7 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
 		   " reusing fd for second head\n");
 
 	info->dri2.drm_fd = pRADEONEnt->fd;
+	pRADEONEnt->fd_ref++;
 	goto out;
     }
 
@@ -596,6 +597,7 @@ static Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
     }
 
     pRADEONEnt->fd = info->dri2.drm_fd;
+    pRADEONEnt->fd_ref = 1;
  out:
     info->drmmode.fd = info->dri2.drm_fd;
     return TRUE;
@@ -1068,7 +1070,6 @@ static Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
     drmmode_fini(pScrn, &info->drmmode);
     if (info->dri2.enabled)
 	radeon_dri2_close_screen(pScreen);
-    drmClose(info->dri2.drm_fd);
 
     pScrn->vtSema = FALSE;
     xf86ClearPrimInitDone(info->pEnt->index);
@@ -1082,10 +1083,19 @@ void RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL)
 {
     SCRN_INFO_PTR(arg);
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONFreeScreen\n");
 
+    if (info->dri2.drm_fd > 0) {
+        pRADEONEnt->fd_ref--;
+        if (!pRADEONEnt->fd_ref) {
+            drmClose(pRADEONEnt->fd);
+            pRADEONEnt->fd = 0;
+        }
+    }
+
     /* when server quits at PreInit, we don't need do this anymore*/
     if (!info) return;
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 516b7b4..1899a16 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -128,7 +128,9 @@ typedef struct
     ScrnInfoPtr pPrimaryScrn;
 
     int fd;                             /* for sharing across zaphod heads   */
+    int fd_ref;
     unsigned long     fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
+    int fd_wakeup_ref;
     int dri2_info_cnt;
 } RADEONEntRec, *RADEONEntPtr;
 


More information about the xorg-commit mailing list