diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-06-22 16:34:20 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-06-22 17:39:39 +0100 |
commit | 41badce186fe0f6e8f49e30b6c1c251027161e35 (patch) | |
tree | 911cf606da6f3169105089b6854ec0809ba2e82a /src/sna/sna_driver.c | |
parent | 81b35092c39bf6d9851ac37da4b20358405cf314 (diff) |
sna: Add reference counting to drmMaster for Zaphod
With Zaphod enabled, we will try to acquire/release the drmMaster
several times on each enter/leave VT. This obviously flags an error (and
drops the master too early), so track the number of references we still
hold for drmMaster.
References: https://bugs.freedesktop.org/show_bug.cgi?id=66041
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_driver.c')
-rw-r--r-- | src/sna/sna_driver.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index b48ab30d..013e27a9 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -78,6 +78,9 @@ DevPrivateKeyRec sna_gc_key; DevPrivateKeyRec sna_window_key; DevPrivateKeyRec sna_glyph_key; +static int sna_put_drm_master(ScrnInfoPtr scrn); +static int sna_get_drm_master(ScrnInfoPtr scrn); + static void sna_load_palette(ScrnInfoPtr scrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) @@ -197,7 +200,7 @@ static Bool sna_become_master(struct sna *sna) DBG(("%s\n", __FUNCTION__)); - if (drmSetMaster(sna->kgem.fd)) { + if (sna_get_drm_master(scrn)) { sleep(2); /* XXX wait for the current master to decease */ if (drmSetMaster(sna->kgem.fd)) { xf86DrvMsg(scrn->scrnIndex, X_ERROR, @@ -293,6 +296,7 @@ static void PreInitCleanup(ScrnInfoPtr scrn) struct sna_device { int fd; int open_count; + int master_count; }; static int sna_device_key = -1; @@ -323,9 +327,10 @@ static int sna_open_drm_master(ScrnInfoPtr scrn) dev = sna_device(scrn); if (dev) { + DBG(("%s: reusing device, count=%d (master=%d)\n", + __FUNCTION__, dev->open_count, dev->master_count)); + assert(dev->open_count); dev->open_count++; - DBG(("%s: reusing device, count=%d\n", - __FUNCTION__, dev->open_count)); return dev->fd; } @@ -375,6 +380,36 @@ static int sna_open_drm_master(ScrnInfoPtr scrn) return fd; } +static int sna_get_drm_master(ScrnInfoPtr scrn) +{ + struct sna_device *dev = sna_device(scrn); + int ret; + + if (dev == NULL) + return -1; + + ret = 0; + if (dev->master_count++ == 0) + ret = drmSetMaster(dev->fd); + return ret; +} + +static int sna_put_drm_master(ScrnInfoPtr scrn) +{ + struct sna_device *dev = sna_device(scrn); + int ret; + + if (dev == NULL) + return -1; + + ret = 0; + assert(dev->master_count); + if (--dev->master_count == 0) + ret = drmDropMaster(dev->fd); + + return ret; +} + static void sna_close_drm_master(ScrnInfoPtr scrn) { struct sna_device *dev = sna_device(scrn); @@ -825,13 +860,12 @@ static void sna_uevent_fini(ScrnInfoPtr scrn) { } static void sna_leave_vt(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); - struct sna *sna = to_sna(scrn); DBG(("%s\n", __FUNCTION__)); xf86_hide_cursors(scrn); - if (drmDropMaster(sna->kgem.fd)) + if (sna_put_drm_master(scrn)) xf86DrvMsg(scrn->scrnIndex, X_WARNING, "drmDropMaster failed: %s\n", strerror(errno)); } |