xf86-video-intel: 14 commits - src/sna/kgem.c src/sna/sna_accel.c src/sna/sna_display.c src/sna/sna_threads.c src/sna/sna_trapezoids_mono.c xvmc/intel_xvmc.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Oct 22 13:04:45 PDT 2013


 src/sna/kgem.c                |    1 
 src/sna/sna_accel.c           |  200 +++++++++++++++++++-----------------------
 src/sna/sna_display.c         |   68 +++++++-------
 src/sna/sna_threads.c         |    4 
 src/sna/sna_trapezoids_mono.c |    2 
 xvmc/intel_xvmc.c             |   42 ++++----
 6 files changed, 154 insertions(+), 163 deletions(-)

New commits:
commit 11e8b299e11ff846e1c8090f7cbd34b2af850d85
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 17:36:58 2013 +0100

    sna: Flush the pending move-to-gpu upon Pixmap free
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index f58092e..497e0d1 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1389,6 +1389,9 @@ static Bool sna_destroy_pixmap(PixmapPtr pixmap)
 		priv->cow = NULL;
 	}
 
+	if (priv->move_to_gpu)
+		(void)priv->move_to_gpu(sna, priv, 0);
+
 	/* Always release the gpu bo back to the lower levels of caching */
 	if (priv->gpu_bo) {
 		sna_pixmap_unmap(pixmap, priv);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 098eeda..7423136 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4285,12 +4285,12 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 
 	assert(wait->bo != priv->gpu_bo);
 
+	if (flags == 0 || pixmap != sna->front || !sna->mode.shadow_damage)
+		goto done;
+
 	if ((flags & MOVE_WRITE) == 0)
 		return true;
 
-	if (pixmap != sna->front || !sna->mode.shadow_damage)
-		goto done;
-
 	assert(sna->mode.shadow_active);
 
 	assert(priv->gpu_bo->refcnt >= 1);
commit 4eb736d61a3b45edb921799b74b3b164b94c174a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 17:35:33 2013 +0100

    sna: Handle pending move-to-gpu for userptr uploads
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 1977d45..f58092e 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4158,11 +4158,19 @@ try_upload_blt(PixmapPtr pixmap, RegionRec *region,
 	assert(priv->gpu_bo);
 	assert(priv->gpu_bo->proxy == NULL);
 
-	if (priv->cow || !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
+	if (!__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)) {
 		DBG(("%s: no, target is idle\n", __FUNCTION__));
 		return false;
 	}
 
+	if (priv->cow || priv->move_to_gpu) {
+		if (!region_subsumes_drawable(region, &pixmap->drawable) ||
+		    !sna_pixmap_move_to_gpu(pixmap, MOVE_WRITE)) {
+			DBG(("%s: no, target is a partial COW\n", __FUNCTION__));
+			return false;
+		}
+	}
+
 	if (priv->cpu_damage &&
 	    sna_damage_contains_box__no_reduce(priv->cpu_damage,
 					       &region->extents) &&
commit c9e304a7194c1fd6038c59524d3c03756ea0d09e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 17:34:59 2013 +0100

    sna: Pass the async hint when pushing GPU damage for redisplay
    
    So that we don't accidentally clear any other hints.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 37307c5..098eeda 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4423,7 +4423,7 @@ void sna_mode_redisplay(struct sna *sna)
 	if (sna->mode.shadow_flip)
 		return;
 
-	if (wedged(sna) || !sna_pixmap_move_to_gpu(sna->front, MOVE_READ)) {
+	if (wedged(sna) || !sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT)) {
 		if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ))
 			return;
 
commit c51dd18eade425a7e280203b328b66d278fcba1c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 16:59:29 2013 +0100

    sna: Fix inconsistency in has_coherent_ptr assertion
    
    We occasionally will read from an "incoherent" ptr in the belief that
    the clflush hit will be worth it.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 954d234..1977d45 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1436,10 +1436,12 @@ static inline bool has_coherent_ptr(struct sna *sna, struct sna_pixmap *priv, un
 		if (!priv->cpu_bo)
 			return true;
 
+		assert(priv->pixmap->devKind == priv->cpu_bo->pitch);
 		return priv->pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu);
 	}
 
 	assert(!priv->move_to_gpu || (flags & MOVE_WRITE) == 0);
+	assert(priv->pixmap->devKind == priv->gpu_bo->pitch);
 
 	if (priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)) {
 		assert(priv->mapped == MAPPED_CPU);
@@ -1447,7 +1449,7 @@ static inline bool has_coherent_ptr(struct sna *sna, struct sna_pixmap *priv, un
 		if (priv->gpu_bo->tiling != I915_TILING_NONE)
 			return false;
 
-		return kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, flags & MOVE_WRITE);
+		return flags & MOVE_READ || kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, flags & MOVE_WRITE);
 	}
 
 	if (priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__gtt)) {
@@ -2027,6 +2029,7 @@ skip_inplace_map:
 		assert(priv->move_to_gpu == NULL || (flags & MOVE_WRITE) == 0);
 
 		assert(!priv->mapped);
+		assert(priv->gpu_bo->tiling == I915_TILING_NONE);
 
 		ptr = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
 		if (ptr != NULL) {
commit bccbbf8a68faf7aac274efd289d4916083b1a1e3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 14:22:14 2013 +0100

    sna: Remove the move-to-gpu shortcircuiting for partial GPU, no CPU damage
    
    Otherwise we may not correctly undo COW or pending move-to-gpu updates.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index fc99a7d..954d234 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3402,21 +3402,8 @@ create_gpu_bo:
 
 	if (priv->gpu_damage) {
 		assert(priv->gpu_bo);
-		if (!priv->cpu_damage) {
-			if (sna_damage_contains_box__no_reduce(priv->gpu_damage,
-							       &region.extents)) {
-				DBG(("%s: region wholly contained within GPU damage\n",
-				     __FUNCTION__));
-				assert(sna_damage_contains_box(priv->gpu_damage, &region.extents) == PIXMAN_REGION_IN);
-				assert(sna_damage_contains_box(priv->cpu_damage, &region.extents) == PIXMAN_REGION_OUT);
-				goto use_gpu_bo;
-			} else {
-				DBG(("%s: partial GPU damage with no CPU damage, continuing to use GPU\n",
-				     __FUNCTION__));
-				priv->cpu = false;
-				goto done;
-			}
-		}
+		if (!priv->cpu_damage)
+			goto use_gpu_bo;
 
 		ret = sna_damage_contains_box(priv->gpu_damage, &region.extents);
 		if (ret == PIXMAN_REGION_IN) {
commit 1c282afb212d1d387d318256f4627385d12e1921
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 13:33:06 2013 +0100

    sna: Make sure CPU damage is flushed to the TearFree shadow
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c72dbb7..fc99a7d 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3709,7 +3709,8 @@ sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags)
 
 	assert_pixmap_damage(pixmap);
 
-	if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, flags)) {
+	if (priv->move_to_gpu &&
+	    !priv->move_to_gpu(sna, priv, flags | (priv->cpu_damage ? MOVE_WRITE : 0))) {
 		DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
 		return NULL;
 	}
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 652b8a1..37307c5 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4423,7 +4423,6 @@ void sna_mode_redisplay(struct sna *sna)
 	if (sna->mode.shadow_flip)
 		return;
 
-	assert(sna_pixmap(sna->front)->move_to_gpu == NULL);
 	if (wedged(sna) || !sna_pixmap_move_to_gpu(sna->front, MOVE_READ)) {
 		if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ))
 			return;
@@ -4451,6 +4450,8 @@ void sna_mode_redisplay(struct sna *sna)
 		return;
 	}
 
+	assert(sna_pixmap(sna->front)->move_to_gpu == NULL);
+
 	for (i = 0; i < config->num_crtc; i++) {
 		xf86CrtcPtr crtc = config->crtc[i];
 		struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
commit 247ebf86a32b518536a11c2f866b2c885bd55d38
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 07:58:03 2013 +0100

    sna: Only force the TearFree exchange before a write
    
    We can read from the current scanout buffer without incurring a visual
    tear, so delay the GPU bo exchange until we see a write to the object.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 97a0f14..c72dbb7 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1432,8 +1432,6 @@ static inline bool has_coherent_ptr(struct sna *sna, struct sna_pixmap *priv, un
 	if (priv == NULL)
 		return true;
 
-	assert(!priv->move_to_gpu);
-
 	if (!priv->mapped) {
 		if (!priv->cpu_bo)
 			return true;
@@ -1441,6 +1439,8 @@ static inline bool has_coherent_ptr(struct sna *sna, struct sna_pixmap *priv, un
 		return priv->pixmap->devPrivate.ptr == MAP(priv->cpu_bo->map__cpu);
 	}
 
+	assert(!priv->move_to_gpu || (flags & MOVE_WRITE) == 0);
+
 	if (priv->pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)) {
 		assert(priv->mapped == MAPPED_CPU);
 
@@ -1475,7 +1475,7 @@ static inline bool pixmap_inplace(struct sna *sna,
 		return false;
 	}
 
-	if (priv->move_to_gpu)
+	if (priv->move_to_gpu && flags & MOVE_WRITE)
 		return false;
 
 	if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo)) {
@@ -1825,7 +1825,7 @@ static inline bool operate_inplace(struct sna_pixmap *priv, unsigned flags)
 
 	assert((flags & MOVE_ASYNC_HINT) == 0);
 
-	if (priv->move_to_gpu) {
+	if (priv->move_to_gpu && flags & MOVE_WRITE) {
 		DBG(("%s: no, has pending move-to-gpu\n", __FUNCTION__));
 		return false;
 	}
@@ -1888,6 +1888,13 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 
 	assert(priv->gpu_damage == NULL || priv->gpu_bo);
 
+	if ((flags & MOVE_READ) == 0 && UNDO) {
+		if (priv->gpu_bo)
+			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
+		if (priv->cpu_bo)
+			kgem_bo_undo(&sna->kgem, priv->cpu_bo);
+	}
+
 	if (DAMAGE_IS_ALL(priv->cpu_damage)) {
 		DBG(("%s: CPU all-damaged\n", __FUNCTION__));
 		assert(priv->gpu_damage == NULL || DAMAGE_IS_ALL(priv->gpu_damage));
@@ -1899,13 +1906,6 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 		return false;
 	}
 
-	if ((flags & MOVE_READ) == 0 && UNDO) {
-		if (priv->gpu_bo)
-			kgem_bo_undo(&sna->kgem, priv->gpu_bo);
-		if (priv->cpu_bo)
-			kgem_bo_undo(&sna->kgem, priv->cpu_bo);
-	}
-
 	if (USE_INPLACE && (flags & MOVE_READ) == 0 && !priv->cow) {
 		assert(flags & MOVE_WRITE);
 		DBG(("%s: no readbck, discarding gpu damage [%d], pending clear[%d]\n",
@@ -1917,9 +1917,9 @@ _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned int flags)
 			void *ptr;
 
 			DBG(("%s: write inplace\n", __FUNCTION__));
-			assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0);
 			assert(!priv->shm);
-			assert(!priv->move_to_gpu);
+			assert(priv->cow == NULL);
+			assert(priv->move_to_gpu == NULL);
 			assert(priv->gpu_bo->exec == NULL);
 			assert((flags & MOVE_READ) == 0 || priv->cpu_damage == NULL);
 
@@ -2015,18 +2015,18 @@ skip_inplace_map:
 
 	if (USE_INPLACE &&
 	    priv->gpu_damage && priv->cpu_damage == NULL &&
-	    !priv->cow && !priv->move_to_gpu &&
 	    priv->gpu_bo->tiling == I915_TILING_NONE &&
 	    (flags & MOVE_READ || kgem_bo_can_map__cpu(&sna->kgem, priv->gpu_bo, flags & MOVE_WRITE)) &&
 	    ((flags & (MOVE_WRITE | MOVE_ASYNC_HINT)) == 0 ||
-	     !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo))) {
+	     (!priv->cow && !priv->move_to_gpu &&
+	      !__kgem_bo_is_busy(&sna->kgem, priv->gpu_bo)))) {
 		void *ptr;
 
 		DBG(("%s: try to operate inplace (CPU)\n", __FUNCTION__));
 		assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0);
+		assert(priv->move_to_gpu == NULL || (flags & MOVE_WRITE) == 0);
 
 		assert(!priv->mapped);
-		assert(!priv->move_to_gpu);
 
 		ptr = kgem_bo_map__cpu(&sna->kgem, priv->gpu_bo);
 		if (ptr != NULL) {
@@ -2389,6 +2389,13 @@ contains_damage:
 		return _sna_pixmap_move_to_cpu(pixmap, flags);
 	}
 
+	if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, MOVE_READ)) {
+		DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
+		if (dx | dy)
+			RegionTranslate(region, -dx, -dy);
+		return false;
+	}
+
 	if (USE_INPLACE &&
 	    operate_inplace(priv, flags) &&
 	    region_inplace(sna, pixmap, region, priv, flags) &&
@@ -2397,7 +2404,7 @@ contains_damage:
 
 		DBG(("%s: try to operate inplace\n", __FUNCTION__));
 		assert(priv->cow == NULL || (flags & MOVE_WRITE) == 0);
-		assert(!priv->move_to_gpu);
+		assert(priv->move_to_gpu == NULL || (flags & MOVE_WRITE) == 0);
 
 		/* XXX only sync for writes? */
 		kgem_bo_submit(&sna->kgem, priv->gpu_bo);
@@ -2443,20 +2450,12 @@ contains_damage:
 		return _sna_pixmap_move_to_cpu(pixmap, flags | MOVE_READ);
 	}
 
-	if (priv->move_to_gpu && !priv->move_to_gpu(sna, priv, MOVE_READ)) {
-		DBG(("%s: move-to-gpu override failed\n", __FUNCTION__));
-		if (dx | dy)
-			RegionTranslate(region, -dx, -dy);
-		return false;
-	}
-
 	sna_pixmap_unmap(pixmap, priv);
 
 	if (USE_INPLACE &&
 	    priv->gpu_damage &&
 	    priv->gpu_bo->tiling == I915_TILING_NONE &&
-	    priv->move_to_gpu == NULL &&
-	    (priv->cow == NULL || (flags & MOVE_WRITE) == 0) &&
+	    ((priv->cow == NULL && priv->move_to_gpu == NULL) || (flags & MOVE_WRITE) == 0) &&
 	    (DAMAGE_IS_ALL(priv->gpu_damage) ||
 	     sna_damage_contains_box__no_reduce(priv->gpu_damage,
 						&region->extents)) &&
@@ -5548,6 +5547,7 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		DBG(("%s: ignoring cow reference for cousin copy\n",
 		     __FUNCTION__));
 		assert(src_priv->cpu_damage == NULL);
+		assert(dst_priv->move_to_gpu == NULL);
 		bo = dst_priv->gpu_bo;
 		damage = NULL;
 	} else {
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index fd8efb5..652b8a1 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -4274,27 +4274,35 @@ struct wait_for_shadow {
 static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned flags)
 {
 	struct wait_for_shadow *wait = priv->move_to_gpu_data;
+	struct kgem_bo *bo = wait->bo;
 	PixmapPtr pixmap = priv->pixmap;
 	DamagePtr damage;
 	bool ret = true;
 
-	damage = sna->mode.shadow_damage;
-	sna->mode.shadow_damage = NULL;
+	DBG(("%s: flags=%x, shadow_flip=%d, handle=%d, wait=%d, old=%d\n",
+	     __FUNCTION__, flags, sna->mode.shadow_flip,
+	     priv->gpu_bo->handle, wait->bo->handle, sna->mode.shadow->handle));
+
+	assert(wait->bo != priv->gpu_bo);
+
+	if ((flags & MOVE_WRITE) == 0)
+		return true;
 
-	if (pixmap != sna->front)
+	if (pixmap != sna->front || !sna->mode.shadow_damage)
 		goto done;
 
-	DBG(("%s: flags=%x, shadow_flip=%d\n", __FUNCTION__,
-	     flags, sna->mode.shadow_flip));
+	assert(sna->mode.shadow_active);
+
+	assert(priv->gpu_bo->refcnt >= 1);
+	sna->mode.shadow = priv->gpu_bo;
+
+	damage = sna->mode.shadow_damage;
+	sna->mode.shadow_damage = NULL;
 
 	while (sna->mode.shadow_flip && sna_mode_has_pending_events(sna))
 		sna_mode_wakeup(sna);
 
-	assert(priv->gpu_bo != sna->mode.shadow);
-
 	if (sna->mode.shadow_flip) {
-		struct kgem_bo *bo;
-
 		bo = kgem_create_2d(&sna->kgem,
 				    pixmap->drawable.width,
 				    pixmap->drawable.height,
@@ -4305,12 +4313,7 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 			DBG(("%s: replacing still-attached GPU bo\n",
 			     __FUNCTION__));
 
-			sna_pixmap_unmap(pixmap, priv);
-			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
-			priv->gpu_bo = bo;
-
-			sna_dri_pixmap_update_bo(sna, pixmap);
-
+			kgem_bo_destroy(&sna->kgem, wait->bo);
 			RegionUninit(&wait->region);
 
 			wait->region.extents.x1 = 0;
@@ -4325,19 +4328,29 @@ static bool wait_for_shadow(struct sna *sna, struct sna_pixmap *priv, unsigned f
 		}
 	}
 
+	sna->mode.shadow_damage = damage;
+
 	if (flags & MOVE_READ) {
 		DBG(("%s: copying existing GPU damage: %ldx(%d, %d), (%d, %d)\n",
 		     __FUNCTION__, (long)REGION_NUM_RECTS(&wait->region),
 		     wait->region.extents.x1, wait->region.extents.y1,
 		     wait->region.extents.x2, wait->region.extents.y2));
 		ret = sna->render.copy_boxes(sna, GXcopy,
-					     pixmap, wait->bo, 0, 0,
 					     pixmap, priv->gpu_bo, 0, 0,
+					     pixmap, bo, 0, 0,
 					     REGION_RECTS(&wait->region),
 					     REGION_NUM_RECTS(&wait->region),
 					     0);
 	}
 
+	if (priv->cow)
+		sna_pixmap_undo_cow(sna, priv, 0);
+
+	sna_pixmap_unmap(pixmap, priv);
+	priv->gpu_bo = bo;
+
+	sna_dri_pixmap_update_bo(sna, pixmap);
+
 done:
 	kgem_bo_destroy(&sna->kgem, wait->bo);
 	RegionUninit(&wait->region);
@@ -4346,8 +4359,6 @@ done:
 	priv->move_to_gpu_data = NULL;
 	priv->move_to_gpu = NULL;
 
-	sna->mode.shadow_damage = damage;
-
 	return ret;
 }
 
@@ -4363,7 +4374,7 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo, RegionPtr region)
 	assert(priv->move_to_gpu == NULL);
 	wait = malloc(sizeof(*wait));
 	if (wait != NULL) {
-		wait->bo = kgem_bo_reference(priv->gpu_bo);
+		wait->bo = kgem_bo_reference(bo);
 		RegionNull(&wait->region);
 		RegionCopy(&wait->region, region);
 
@@ -4371,12 +4382,6 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo, RegionPtr region)
 		priv->move_to_gpu_data = wait;
 	}
 
-	if (priv->cow)
-		sna_pixmap_undo_cow(to_sna_from_pixmap(pixmap), priv, 0);
-
-	sna_pixmap_unmap(pixmap, priv);
-
-	priv->gpu_bo = bo;
 	priv->pinned |= PIN_SCANOUT;
 }
 
@@ -4499,7 +4504,7 @@ void sna_mode_redisplay(struct sna *sna)
 
 				if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
 					DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
-					     __FUNCTION__, arg.fb_id, i, crtc->id, crtc->pipe, errno));
+					     __FUNCTION__, arg.fb_id, i, sna_crtc->id, sna_crtc->pipe, errno));
 disable1:
 					xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
 						   "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
@@ -4570,12 +4575,9 @@ disable2:
 		}
 
 		if (sna->mode.shadow) {
+			assert(old == sna->mode.shadow);
 			assert(old->refcnt >= 1);
-
 			set_bo(sna->front, old, region);
-			sna_dri_pixmap_update_bo(sna, sna->front);
-
-			sna->mode.shadow = new;
 		}
 	} else
 		kgem_submit(&sna->kgem);
commit 7b78f25d8992e56f83c897c3d2d7dd75cb7dd1d6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 15:54:59 2013 +0100

    xvmc: Handle errors along allocation path
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/xvmc/intel_xvmc.c b/xvmc/intel_xvmc.c
index 1d7b6e2..ff13d03 100644
--- a/xvmc/intel_xvmc.c
+++ b/xvmc/intel_xvmc.c
@@ -408,21 +408,18 @@ _X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context,
 
 	surface->privData = calloc(1, sizeof(struct intel_xvmc_surface));
 
-	if (!(intel_surf = surface->privData)) {
-		PPTHREAD_MUTEX_UNLOCK();
-		return BadAlloc;
-	}
+	if (!(intel_surf = surface->privData))
+		goto out_xvmc;
 
 	intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
 					      "surface",
 					      intel_ctx->surface_bo_size,
 					      GTT_PAGE_SIZE);
-	if (!intel_surf->bo) {
-		free(intel_surf);
-		return BadAlloc;
-	}
+	if (!intel_surf->bo)
+		goto out_surf;
 
-	drm_intel_bo_disable_reuse(intel_surf->bo);
+	if (drm_intel_bo_flink(intel_surf->bo, &intel_surf->gem_handle))
+		goto out_bo;
 
 	intel_surf = surface->privData;
 	intel_surf->context = context;
@@ -433,12 +430,18 @@ _X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context,
 					  surface->width, surface->height);
 	if (!intel_surf->image) {
 		XVMC_ERR("Can't create XvImage for surface\n");
-		free(intel_surf);
-		_xvmc_destroy_surface(display, surface);
-		return BadAlloc;
+		goto out_bo;
 	}
 
 	return Success;
+
+out_bo:
+	drm_intel_bo_unreference(intel_surf->bo);
+out_surf:
+	free(intel_surf);
+out_xvmc:
+	_xvmc_destroy_surface(display, surface);
+	return BadAlloc;
 }
 
 /*
@@ -632,7 +635,6 @@ _X_EXPORT Status XvMCPutSurface(Display * display, XvMCSurface * surface,
 				unsigned short destw, unsigned short desth,
 				int flags)
 {
-	Status ret = Success;
 	XvMCContext *context;
 	intel_xvmc_surface_ptr intel_surf;
 
@@ -640,8 +642,11 @@ _X_EXPORT Status XvMCPutSurface(Display * display, XvMCSurface * surface,
 		return XvMCBadSurface;
 
 	intel_surf = surface->privData;
+	if (!intel_surf)
+		return XvMCBadSurface;
+
 	context = intel_surf->context;
-	if (!context || !intel_surf)
+	if (!context)
 		return XvMCBadSurface;
 
 	if (intel_surf->gc_init == FALSE) {
@@ -653,12 +658,9 @@ _X_EXPORT Status XvMCPutSurface(Display * display, XvMCSurface * surface,
 	}
 	intel_surf->last_draw = draw;
 
-	drm_intel_bo_flink(intel_surf->bo, &intel_surf->gem_handle);
-
-	ret = XvPutImage(display, context->port, draw, intel_surf->gc,
-			 intel_surf->image, srcx, srcy, srcw, srch, destx,
-			 desty, destw, desth);
-	return ret;
+	return XvPutImage(display, context->port, draw, intel_surf->gc,
+			  intel_surf->image, srcx, srcy, srcw, srch, destx,
+			  desty, destw, desth);
 }
 
 /*
commit 27249537d7a2c0c9f817716d657224175a2d9acb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 15:35:31 2013 +0100

    sna: Free our CRTC private after failing to create the xf86Crtc
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index fbd81d0..fd8efb5 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -1818,6 +1818,7 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
 	sna_crtc->cursor = gem_create(sna->kgem.fd, 64*64*4);
 	if (!sna_crtc->cursor) {
 		xf86CrtcDestroy(crtc);
+		free(sna_crtc);
 		return false;
 	}
 	DBG(("%s: created handle=%d for cursor on CRTC:%d\n",
commit 9fcda71d753ab5126143f053c47513e9acf5c98b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 15:32:23 2013 +0100

    sna/trapezoids: Fix inversion of initialisation test for triangles
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_trapezoids_mono.c b/src/sna/sna_trapezoids_mono.c
index 2f7a2bb..f7b9a1c 100644
--- a/src/sna/sna_trapezoids_mono.c
+++ b/src/sna/sna_trapezoids_mono.c
@@ -1341,7 +1341,7 @@ mono_triangles_span_converter(struct sna *sna,
 
 	was_clear = sna_drawable_is_clear(dst->pDrawable);
 
-	if (mono_init(&mono, 3*count))
+	if (!mono_init(&mono, 3*count))
 		return false;
 
 	for (n = 0; n < count; n++) {
commit 9fc95bebe783341aaf0e285ca2e216035378943c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 15:30:05 2013 +0100

    sna: Ignore overflow in CPU count rather than abort
    
    If there are more processors than we ever expect, good! Just use lots of
    them, rather than none at all.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_threads.c b/src/sna/sna_threads.c
index 333b7eb..6627cbd 100644
--- a/src/sna/sna_threads.c
+++ b/src/sna/sna_threads.c
@@ -102,11 +102,11 @@ num_cores(void)
 			int id;
 			if (sscanf(line, "physical id : %d", &id) == 1) {
 				if (id >= 32)
-					return 0;
+					continue;
 				processors |= 1 << id;
 			} else if (sscanf(line, "core id : %d", &id) == 1) {
 				if (id >= 32)
-					return 0;
+					continue;
 				cores |= 1 << id;
 			}
 		}
commit e3f15cbf39696edae9f716bdcfbb7032ec7d7e3f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 15:19:15 2013 +0100

    sna: Move gc back to GPU after failure to move it to CPU
    
    As the failure in gc move-to-cpu occurs late, i.e. after the function
    pointers are updated to point to CPU functions, we need to undo those
    changes, i.e. call move-to-gpu for the GC on failure.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 5446e10..97a0f14 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -4808,7 +4808,7 @@ fallback:
 					      format == XYPixmap ?
 					      MOVE_READ | MOVE_WRITE :
 					      drawable_gc_flags(drawable, gc, false)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fbPutImage(%d, %d, %d, %d)\n",
@@ -4817,9 +4817,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 }
 
@@ -5088,11 +5087,11 @@ fallback:
 			}
 
 			if (gc)
+out:
 				sna_gc_move_to_gpu(gc);
 		}
 	}
 
-out:
 	if (box != RegionRects(region))
 		free(box);
 }
@@ -6029,10 +6028,8 @@ fallback:
 
 			RegionTranslate(region, -dst_dx, -dst_dy);
 
-			if (!sna_gc_move_to_cpu(gc, dst, region))
-				return;
-
-			if (sigtrap_get() == 0) {
+			if (sna_gc_move_to_cpu(gc, dst, region) &&
+			    sigtrap_get() == 0) {
 				miCopyRegion(src, dst, gc,
 					     region, dx, dy,
 					     fbCopyNtoN, 0, NULL);
@@ -6190,22 +6187,22 @@ sna_fallback_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	     dx, dy, gc->alu));
 
 	if (!sna_gc_move_to_cpu(gc, dst, region))
-		return;
+		goto out;
 
 	RegionTranslate(region, dx, dy);
 	if (!sna_drawable_move_region_to_cpu(src, region, MOVE_READ))
-		goto out_gc;
+		goto out;
 	RegionTranslate(region, -dx, -dy);
 
 	if (src == dst ||
 	    get_drawable_pixmap(src) == get_drawable_pixmap(dst)) {
 		DBG(("%s: self-copy\n", __FUNCTION__));
 		if (!sna_drawable_move_to_cpu(dst, MOVE_WRITE | MOVE_READ))
-			goto out_gc;
+			goto out;
 	} else {
 		if (!sna_drawable_move_region_to_cpu(dst, region,
 						     drawable_gc_flags(dst, gc, false)))
-			goto out_gc;
+			goto out;
 	}
 
 	if (sigtrap_get() == 0) {
@@ -6215,7 +6212,7 @@ sna_fallback_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		FALLBACK_FLUSH(dst);
 		sigtrap_put();
 	}
-out_gc:
+out:
 	sna_gc_move_to_gpu(gc);
 }
 
@@ -7245,7 +7242,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region,
 					     drawable_gc_flags(drawable, gc, n > 1)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fbFillSpans\n", __FUNCTION__));
@@ -7253,9 +7250,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 }
 
@@ -7288,7 +7284,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region,
 					     drawable_gc_flags(drawable, gc, n > 1)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fbSetSpans\n", __FUNCTION__));
@@ -7296,9 +7292,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 }
 
@@ -7787,7 +7782,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(dst, &region,
 					     drawable_gc_flags(dst, gc, false)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fbCopyPlane(%d, %d, %d, %d, %d,%d) %x\n",
@@ -7799,9 +7794,8 @@ fallback:
 		FALLBACK_FLUSH(dst);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 	return ret;
 empty:
@@ -8001,7 +7995,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region,
 					     MOVE_READ | MOVE_WRITE))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fbPolyPoint\n", __FUNCTION__));
@@ -8009,9 +8003,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 }
 
@@ -9048,7 +9041,7 @@ fallback:
 	if (!sna_drawable_move_region_to_cpu(drawable, &data.region,
 					     drawable_gc_flags(drawable, gc,
 							       !(data.flags & 4 && n == 2))))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fbPolyLine\n", __FUNCTION__));
@@ -9056,9 +9049,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&data.region);
 }
 
@@ -9901,7 +9893,7 @@ fallback:
 	if (!sna_drawable_move_region_to_cpu(drawable, &data.region,
 					     drawable_gc_flags(drawable, gc,
 							       !(data.flags & 4 && n == 1))))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fbPolySegment\n", __FUNCTION__));
@@ -9909,9 +9901,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&data.region);
 }
 
@@ -10512,7 +10503,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region,
 					     drawable_gc_flags(drawable, gc, true)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: miPolyRectangle\n", __FUNCTION__));
@@ -10520,9 +10511,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 }
 
@@ -10715,7 +10705,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(drawable, &data.region,
 					     drawable_gc_flags(drawable, gc, true)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s -- fbPolyArc\n", __FUNCTION__));
@@ -10723,9 +10713,8 @@ fallback:
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&data.region);
 }
 
@@ -11072,7 +11061,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(draw, &data.region,
 					     drawable_gc_flags(draw, gc, true)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fallback -- miFillPolygon -> sna_fill_spans__cpu\n",
@@ -11080,9 +11069,8 @@ fallback:
 		miFillPolygon(draw, gc, shape, mode, n, pt);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&data.region);
 }
 
@@ -13354,7 +13342,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(draw, &region,
 					     drawable_gc_flags(draw, gc, n > 1)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fallback - fbPolyFillRect\n", __FUNCTION__));
@@ -13362,9 +13350,8 @@ fallback:
 		FALLBACK_FLUSH(draw);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 }
 
@@ -13527,7 +13514,7 @@ fallback:
 		goto out;
 	if (!sna_drawable_move_region_to_cpu(draw, &data.region,
 					     drawable_gc_flags(draw, gc, true)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fallback -- miPolyFillArc -> sna_fill_spans__cpu\n",
@@ -13535,9 +13522,8 @@ fallback:
 		miPolyFillArc(draw, gc, n, arc);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&data.region);
 }
 
@@ -14022,7 +14008,7 @@ fallback:
 			goto out;
 		if (!sna_drawable_move_region_to_cpu(drawable, &region,
 						     MOVE_READ | MOVE_WRITE))
-			goto out_gc;
+			goto out;
 
 		if (sigtrap_get() == 0) {
 			DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
@@ -14031,10 +14017,9 @@ fallback:
 			FALLBACK_FLUSH(drawable);
 			sigtrap_put();
 		}
-out_gc:
+out:
 		sna_gc_move_to_gpu(gc);
 	}
-out:
 	RegionUninit(&region);
 	return x + extents.overallRight;
 }
@@ -14100,7 +14085,7 @@ fallback:
 			goto out;
 		if (!sna_drawable_move_region_to_cpu(drawable, &region,
 						     MOVE_READ | MOVE_WRITE))
-			goto out_gc;
+			goto out;
 
 		if (sigtrap_get() == 0) {
 			DBG(("%s: fallback -- fbPolyGlyphBlt\n", __FUNCTION__));
@@ -14109,10 +14094,9 @@ fallback:
 			FALLBACK_FLUSH(drawable);
 			sigtrap_put();
 		}
-out_gc:
+out:
 		sna_gc_move_to_gpu(gc);
 	}
-out:
 	RegionUninit(&region);
 	return x + extents.overallRight;
 }
@@ -14185,7 +14169,7 @@ fallback:
 		if (!sna_gc_move_to_cpu(gc, drawable, &region))
 			goto out;
 		if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_WRITE))
-			goto out_gc;
+			goto out;
 
 		if (sigtrap_get() == 0) {
 			DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
@@ -14194,10 +14178,9 @@ fallback:
 			FALLBACK_FLUSH(drawable);
 			sigtrap_put();
 		}
-out_gc:
+out:
 		sna_gc_move_to_gpu(gc);
 	}
-out:
 	RegionUninit(&region);
 }
 
@@ -14270,7 +14253,7 @@ fallback:
 		if (!sna_gc_move_to_cpu(gc, drawable, &region))
 			goto out;
 		if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_WRITE))
-			goto out_gc;
+			goto out;
 
 		if (sigtrap_get() == 0) {
 			DBG(("%s: fallback -- fbImageGlyphBlt\n", __FUNCTION__));
@@ -14279,10 +14262,9 @@ fallback:
 			FALLBACK_FLUSH(drawable);
 			sigtrap_put();
 		}
-out_gc:
+out:
 		sna_gc_move_to_gpu(gc);
 	}
-out:
 	RegionUninit(&region);
 }
 
@@ -14599,7 +14581,7 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 fallback:
 	DBG(("%s: fallback\n", __FUNCTION__));
 	if (!sna_gc_move_to_cpu(gc, drawable, &region))
-		goto out;
+		goto out_gc;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region, MOVE_WRITE))
 		goto out_gc;
 
@@ -14680,7 +14662,7 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 fallback:
 	DBG(("%s: fallback\n", __FUNCTION__));
 	if (!sna_gc_move_to_cpu(gc, drawable, &region))
-		goto out;
+		goto out_gc;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region,
 					     MOVE_READ | MOVE_WRITE))
 		goto out_gc;
@@ -14867,10 +14849,10 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
 	if (!sna_gc_move_to_cpu(gc, drawable, &region))
 		goto out;
 	if (!sna_pixmap_move_to_cpu(bitmap, MOVE_READ))
-		goto out_gc;
+		goto out;
 	if (!sna_drawable_move_region_to_cpu(drawable, &region,
 					     drawable_gc_flags(drawable, gc, false)))
-		goto out_gc;
+		goto out;
 
 	if (sigtrap_get() == 0) {
 		DBG(("%s: fallback, fbPushPixels(%d, %d, %d %d)\n",
@@ -14879,9 +14861,8 @@ sna_push_pixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
 		FALLBACK_FLUSH(drawable);
 		sigtrap_put();
 	}
-out_gc:
-	sna_gc_move_to_gpu(gc);
 out:
+	sna_gc_move_to_gpu(gc);
 	RegionUninit(&region);
 }
 
commit 0d18b3956501e53e2ea6b5afcdf9af2f587fbc84
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 15:02:53 2013 +0100

    sna: Discard GPU bo when failing to setup the shared pixmap
    
    If we fail to mmap the pixmap when preparing it for use with prime, be
    sure to throw away the now lost priv->gpu_bo.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 31b4230..5446e10 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1183,6 +1183,7 @@ sna_create_pixmap_shared(struct sna *sna, ScreenPtr screen,
 		pixmap->devPrivate.ptr =
 			kgem_bo_map__async(&sna->kgem, priv->gpu_bo);
 		if (pixmap->devPrivate.ptr == NULL) {
+			kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
 			free(priv);
 			FreePixmap(pixmap);
 			return FALSE;
commit c0f31d822a2b10bc30ff2532b5ff87d2f401bc62
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Oct 22 15:00:16 2013 +0100

    sna: Free bo along unlikely one-off error path
    
    Add a missing free for a never-hit error.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f959875..74af421 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1052,6 +1052,7 @@ static bool kgem_init_pinned_batches(struct kgem *kgem)
 			pin.alignment = 0;
 			if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_PIN, &pin)) {
 				gem_close(kgem->fd, pin.handle);
+				free(bo);
 				goto err;
 			}
 			bo->presumed_offset = pin.offset;


More information about the xorg-commit mailing list