xf86-video-intel: 3 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_dri.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Nov 9 04:52:54 PST 2011


 src/sna/kgem.c    |  109 +++++++++++++++++++++++++++++-------------------------
 src/sna/kgem.h    |    3 -
 src/sna/sna_dri.c |    3 -
 3 files changed, 62 insertions(+), 53 deletions(-)

New commits:
commit 436a78684507129ca1245e065ff68870eb27624b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 9 12:48:27 2011 +0000

    sna: Track purgeability separately from reusability
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index f303094..a55086a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -263,6 +263,7 @@ static struct kgem_bo *__kgem_bo_init(struct kgem_bo *bo,
 	bo->handle = handle;
 	bo->size = size;
 	bo->reusable = true;
+	bo->purgeable = true;
 	bo->cpu_read = true;
 	bo->cpu_write = true;
 	list_init(&bo->request);
@@ -601,24 +602,26 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	if(!bo->reusable)
 		goto destroy;
 
-	if (!bo->deleted && !bo->exec) {
+	if (bo->purgeable && !bo->rq) {
+		assert(!bo->purged);
+
 		if (!gem_madvise(kgem->fd, bo->handle, I915_MADV_DONTNEED)) {
 			kgem->need_purge |= bo->gpu;
 			goto destroy;
 		}
 
-		bo->deleted = 1;
+		bo->purged = true;
 	}
 
 	kgem->need_expire = true;
 	if (bo->rq) {
 		list_move(&bo->list, active(kgem, bo->size));
-	} else if (bo->needs_flush | bo->gpu) {
+	} else if (bo->purged) {
+		list_move(&bo->list, inactive(kgem, bo->size));
+	} else {
 		assert(list_is_empty(&bo->request));
 		list_add(&bo->request, &kgem->flushing);
 		list_move(&bo->list, active(kgem, bo->size));
-	} else {
-		list_move(&bo->list, inactive(kgem, bo->size));
 	}
 
 	return;
@@ -647,10 +650,16 @@ bool kgem_retire(struct kgem *kgem)
 
 		DBG(("%s: moving %d from flush to inactive\n",
 		     __FUNCTION__, bo->handle));
-		bo->needs_flush = 0;
-		bo->gpu = false;
-		list_move(&bo->list, inactive(kgem, bo->size));
-		list_del(&bo->request);
+		if (bo->purgeable &&
+		    gem_madvise(kgem->fd, bo->handle, I915_MADV_DONTNEED)) {
+			bo->purged = true;
+			bo->needs_flush = false;
+			bo->gpu = false;
+			list_move(&bo->list, inactive(kgem, bo->size));
+			list_del(&bo->request);
+		} else
+			kgem_bo_free(kgem, bo);
+
 		retired = true;
 	}
 
@@ -682,17 +691,23 @@ bool kgem_retire(struct kgem *kgem)
 
 			if (bo->refcnt == 0) {
 				if (bo->reusable) {
-					assert(bo->deleted);
-					if (bo->needs_flush) {
+					if (bo->needs_flush || !bo->purgeable) {
 						DBG(("%s: moving %d to flushing\n",
 						     __FUNCTION__, bo->handle));
 						list_add(&bo->request, &kgem->flushing);
-					} else {
+					} else if(gem_madvise(kgem->fd,
+							      bo->handle,
+							      I915_MADV_DONTNEED)) {
 						DBG(("%s: moving %d to inactive\n",
 						     __FUNCTION__, bo->handle));
+						bo->purged = true;
 						list_move(&bo->list,
 							  inactive(kgem, bo->size));
 						retired = true;
+					} else {
+						DBG(("%s: closing %d\n",
+						     __FUNCTION__, bo->handle));
+						kgem_bo_free(kgem, bo);
 					}
 				} else {
 					DBG(("%s: closing %d\n",
@@ -705,10 +720,9 @@ bool kgem_retire(struct kgem *kgem)
 		rq->bo->refcnt--;
 		assert(rq->bo->refcnt == 0);
 		if (gem_madvise(kgem->fd, rq->bo->handle, I915_MADV_DONTNEED)) {
-			rq->bo->deleted = 1;
+			rq->bo->purged = true;
 			assert(rq->bo->gpu == 0);
-			list_move(&rq->bo->list,
-				  inactive(kgem, rq->bo->size));
+			list_move(&rq->bo->list, inactive(kgem, rq->bo->size));
 			retired = true;
 		} else {
 			kgem->need_purge = 1;
@@ -740,19 +754,9 @@ static void kgem_commit(struct kgem *kgem)
 		bo->cpu_read = false;
 		bo->cpu_write = false;
 
-		if (!bo->refcnt) {
-			if (!bo->reusable) {
-destroy:			kgem_bo_free(kgem, bo);
-				continue;
-			}
-			if (!bo->deleted) {
-				if (!gem_madvise(kgem->fd, bo->handle,
-						 I915_MADV_DONTNEED)) {
-					kgem->need_purge = 1;
-					goto destroy;
-				}
-				bo->deleted = 1;
-			}
+		if (!bo->refcnt && !bo->reusable) {
+			kgem_bo_free(kgem, bo);
+			continue;
 		}
 	}
 
@@ -807,6 +811,7 @@ static void kgem_finish_partials(struct kgem *kgem)
 			if (base) {
 				memcpy(base, &bo->base, sizeof (*base));
 				base->reusable = true;
+				base->purgeable = true;
 				list_init(&base->list);
 				list_replace(&bo->base.request, &base->request);
 				free(bo);
@@ -1041,7 +1046,7 @@ void _kgem_submit(struct kgem *kgem)
 					       found ? found->size : -1,
 					       found ? found->tiling : -1,
 					       (int)(kgem->exec[i].flags & EXEC_OBJECT_NEEDS_FENCE),
-					       found ? found->deleted : -1);
+					       found ? found->purged : -1);
 				}
 				for (i = 0; i < kgem->nreloc; i++) {
 					ErrorF("reloc[%d] = pos:%d, target:%d, delta:%d, read:%x, write:%x, offset:%x\n",
@@ -1137,7 +1142,7 @@ bool kgem_expire_cache(struct kgem *kgem)
 	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
 		idle &= list_is_empty(&kgem->inactive[i]);
 		list_for_each_entry(bo, &kgem->inactive[i], list) {
-			assert(bo->deleted);
+			assert(bo->purged);
 			if (bo->delta) {
 				expire = now - 5;
 				break;
@@ -1235,14 +1240,14 @@ search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
 		if (use_active && bo->tiling != I915_TILING_NONE)
 			continue;
 
-		if (bo->deleted) {
+		if (bo->purged) {
 			if (!gem_madvise(kgem->fd, bo->handle,
 					 I915_MADV_WILLNEED)) {
 				kgem->need_purge |= bo->gpu;
 				continue;
 			}
 
-			bo->deleted = 0;
+			bo->purged = false;
 		}
 
 		if (I915_TILING_NONE != bo->tiling &&
@@ -1262,6 +1267,7 @@ search_linear_cache(struct kgem *kgem, unsigned int size, bool use_active)
 		     use_active ? "active" : "inactive"));
 		assert(bo->refcnt == 0);
 		assert(bo->reusable);
+		assert(use_active || bo->purgeable);
 		assert(use_active || bo->gpu == 0);
 		//assert(use_active || !kgem_busy(kgem, bo->handle));
 		return bo;
@@ -1290,6 +1296,7 @@ struct kgem_bo *kgem_create_for_name(struct kgem *kgem, uint32_t name)
 	}
 
 	bo->reusable = false;
+	bo->purgeable = false;
 	return bo;
 }
 
@@ -1507,7 +1514,7 @@ search_active: /* Best active match first */
 			if (bo->rq == NULL)
 				list_del(&bo->request);
 
-			if (bo->deleted) {
+			if (bo->purged) {
 				if (!gem_madvise(kgem->fd, bo->handle,
 						 I915_MADV_WILLNEED)) {
 					kgem->need_purge |= bo->gpu;
@@ -1516,7 +1523,7 @@ search_active: /* Best active match first */
 					goto search_active;
 				}
 
-				bo->deleted = 0;
+				bo->purged = false;
 			}
 
 			bo->unique_id = kgem_get_unique_id(kgem);
@@ -1553,14 +1560,14 @@ skip_active_search:
 		list_del(&bo->list);
 		assert(list_is_empty(&bo->request));
 
-		if (bo->deleted) {
+		if (bo->purged) {
 			if (!gem_madvise(kgem->fd, bo->handle,
 					 I915_MADV_WILLNEED)) {
 				kgem->need_purge |= bo->gpu;
 				goto next_bo;
 			}
 
-			bo->deleted = 0;
+			bo->purged = false;
 		}
 
 		bo->delta = 0;
@@ -1570,6 +1577,7 @@ skip_active_search:
 		     bo->pitch, bo->tiling, bo->handle, bo->unique_id));
 		assert(bo->refcnt == 0);
 		assert(bo->reusable);
+		assert(bo->purgeable);
 		assert((flags & CREATE_INACTIVE) == 0 || bo->gpu == 0);
 		assert((flags & CREATE_INACTIVE) == 0 ||
 		       !kgem_busy(kgem, bo->handle));
@@ -1722,7 +1730,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
 	assert(index < ARRAY_SIZE(kgem->reloc));
 	kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
 	if (bo) {
-		assert(!bo->deleted);
+		assert(!bo->purged);
 
 		delta += bo->delta;
 		if (bo->proxy) {
@@ -1732,7 +1740,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
 			bo = bo->proxy;
 		}
 
-		assert(!bo->deleted);
+		assert(!bo->purged);
 
 		if (bo->exec == NULL) {
 			_kgem_add_bo(kgem, bo);
@@ -1802,7 +1810,7 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo)
 	 * on the buffer, and *presuming* they do not pass it on to a third
 	 * party, we track the lifetime accurately.
 	 */
-	bo->reusable = false;
+	bo->purgeable = false;
 	return flink.name;
 }
 
@@ -1844,7 +1852,7 @@ struct kgem_bo *kgem_create_map(struct kgem *kgem,
 		return NULL;
 	}
 
-	bo->reusable = false;
+	bo->purgeable = bo->reusable = false;
 	bo->sync = true;
 	DBG(("%s(ptr=%p, size=%d, read_only=%d) => handle=%d\n",
 	     __FUNCTION__, ptr, size, read_only, handle));
@@ -1973,7 +1981,7 @@ struct kgem_bo *kgem_create_proxy(struct kgem_bo *target,
 	if (bo == NULL)
 		return NULL;
 
-	bo->reusable = false;
+	bo->purgeable = bo->reusable = false;
 	bo->proxy = kgem_bo_reference(target);
 	bo->delta = offset;
 	return bo;
@@ -2102,7 +2110,7 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 		bo->base.vmap = true;
 		bo->need_io = 0;
 	}
-	bo->base.reusable = false;
+	bo->base.purgeable = bo->base.reusable = false;
 
 	bo->alloc = alloc;
 	bo->used = size;
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index e801a15..0f142b7 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -75,7 +75,8 @@ struct kgem_bo {
 	uint32_t vmap : 1;
 	uint32_t flush : 1;
 	uint32_t sync : 1;
-	uint32_t deleted : 1;
+	uint32_t purgeable : 1;
+	uint32_t purged : 1;
 };
 
 struct kgem_request {
commit 2699c01a396b644a35a9acb969ab556454be3517
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 9 12:27:52 2011 +0000

    sna: Handle non-reusable bo more correctly during retire
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 22149ce..f303094 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -681,17 +681,19 @@ bool kgem_retire(struct kgem *kgem)
 			bo->gpu = bo->needs_flush;
 
 			if (bo->refcnt == 0) {
-				assert(bo->deleted);
-				if (bo->needs_flush) {
-					DBG(("%s: moving %d to flushing\n",
-					     __FUNCTION__, bo->handle));
-					list_add(&bo->request, &kgem->flushing);
-				} else if (bo->reusable) {
-					DBG(("%s: moving %d to inactive\n",
-					     __FUNCTION__, bo->handle));
-					list_move(&bo->list,
-						  inactive(kgem, bo->size));
-					retired = true;
+				if (bo->reusable) {
+					assert(bo->deleted);
+					if (bo->needs_flush) {
+						DBG(("%s: moving %d to flushing\n",
+						     __FUNCTION__, bo->handle));
+						list_add(&bo->request, &kgem->flushing);
+					} else {
+						DBG(("%s: moving %d to inactive\n",
+						     __FUNCTION__, bo->handle));
+						list_move(&bo->list,
+							  inactive(kgem, bo->size));
+						retired = true;
+					}
 				} else {
 					DBG(("%s: closing %d\n",
 					     __FUNCTION__, bo->handle));
commit fcc89d26600a57317007035fa720915e8a2ade81
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 9 12:25:43 2011 +0000

    sna: Safety first; make all flinked bo unreusable
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 8ef5783..22149ce 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1800,6 +1800,7 @@ uint32_t kgem_bo_flink(struct kgem *kgem, struct kgem_bo *bo)
 	 * on the buffer, and *presuming* they do not pass it on to a third
 	 * party, we track the lifetime accurately.
 	 */
+	bo->reusable = false;
 	return flink.name;
 }
 
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index d21cfb1..f0fcb94 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -152,7 +152,6 @@ static struct kgem_bo *sna_pixmap_set_dri(struct sna *sna,
 
 	/* The bo is outside of our control, so presume it is written to */
 	priv->gpu_bo->needs_flush = true;
-	priv->gpu_bo->reusable = false;
 	priv->gpu_bo->gpu = true;
 
 	/* We need to submit any modifications to and reads from this
@@ -202,7 +201,6 @@ sna_dri_create_buffer(DrawablePtr drawable,
 		pixmap = get_drawable_pixmap(drawable);
 		pixmap->refcnt++;
 		bo = sna_pixmap_set_dri(sna, pixmap);
-		bo->reusable = true;
 		bpp = pixmap->drawable.bitsPerPixel;
 		DBG(("%s: attaching to front buffer %dx%d [%p:%d]\n",
 		     __FUNCTION__,
@@ -953,7 +951,6 @@ static void set_pixmap(struct sna *sna, DRI2BufferPtr buffer, PixmapPtr pixmap)
 	priv->pixmap->refcnt--;
 	priv->pixmap = pixmap;
 	priv->bo = sna_pixmap_set_dri(sna, pixmap);
-	priv->bo->reusable = true;
 	buffer->name = kgem_bo_flink(&sna->kgem, priv->bo);
 	buffer->pitch = priv->bo->pitch;
 }


More information about the xorg-commit mailing list