xf86-video-intel: 2 commits - src/sna/kgem.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Jul 5 16:27:04 PDT 2011


 src/sna/kgem.c |  143 ++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 87 insertions(+), 56 deletions(-)

New commits:
commit d6afd66461ebcdc2e8dcd94b3f46f374d8acf469
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 5 23:12:59 2011 +0100

    sna: Reset unused partial buffers
    
    Whilst searching for available space on the active partial buffer list,
    if we discover an unreferenced one, reset its used counter to zero.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 46380a8..805677a 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1773,78 +1773,84 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 {
 	struct kgem_partial_bo *bo;
 	bool write = !!(flags & KGEM_BUFFER_WRITE);
-	int offset = 0;
+	int offset, alloc;
+	uint32_t handle;
 
 	DBG(("%s: size=%d, flags=%x\n", __FUNCTION__, size, flags));
 
 	list_for_each_entry(bo, &kgem->partial, base.list) {
 		if (bo->write != write)
 			continue;
+
+		if (bo->base.refcnt == 1)
+			/* no users, so reset */
+			bo->used = 0;
+
 		if (bo->used + size < bo->alloc) {
-			DBG(("%s: reusing partial buffer? used=%d, total=%d\n",
-			     __FUNCTION__, bo->used, bo->alloc));
+			DBG(("%s: reusing partial buffer? used=%d + size=%d, total=%d\n",
+			     __FUNCTION__, bo->used, size, bo->alloc));
 			offset = bo->used;
 			bo->used += size;
-			break;
+			if (kgem->partial.next != &bo->base.list)
+				list_move(&bo->base.list, &kgem->partial);
+			goto done;
 		}
 	}
 
-	if (offset == 0) {
-		uint32_t handle;
-		int alloc;
-
-		alloc = (flags & KGEM_BUFFER_LAST) ? 4096 : 32 * 1024;
-		alloc = ALIGN(size, alloc);
-
-		bo = malloc(sizeof(*bo) + alloc);
-		if (bo == NULL)
-			return NULL;
-
-		handle = 0;
-		if (kgem->has_vmap)
-			handle = gem_vmap(kgem->fd, bo+1, alloc, write);
-		if (handle == 0) {
-			struct kgem_bo *old;
-
-			old = NULL;
-			if (!write)
-				old = search_linear_cache(kgem, alloc, true);
-			if (old == NULL)
-				old = search_linear_cache(kgem, alloc, false);
-			if (old) {
-				memcpy(&bo->base, old, sizeof(*old));
-				if (old->rq)
-					list_replace(&old->request,
-						     &bo->base.request);
-				else
-					list_init(&bo->base.request);
-				free(old);
-				bo->base.refcnt = 1;
-			} else {
-				if (!__kgem_bo_init(&bo->base,
-					       gem_create(kgem->fd, alloc),
-					       alloc)) {
-					free(bo);
-					return NULL;
-				}
-			}
-			bo->need_io = true;
+
+	alloc = (flags & KGEM_BUFFER_LAST) ? 4096 : 32 * 1024;
+	alloc = ALIGN(size, alloc);
+
+	bo = malloc(sizeof(*bo) + alloc);
+	if (bo == NULL)
+		return NULL;
+
+	handle = 0;
+	if (kgem->has_vmap)
+		handle = gem_vmap(kgem->fd, bo+1, alloc, write);
+	if (handle == 0) {
+		struct kgem_bo *old;
+
+		old = NULL;
+		if (!write)
+			old = search_linear_cache(kgem, alloc, true);
+		if (old == NULL)
+			old = search_linear_cache(kgem, alloc, false);
+		if (old) {
+			memcpy(&bo->base, old, sizeof(*old));
+			if (old->rq)
+				list_replace(&old->request,
+					     &bo->base.request);
+			else
+				list_init(&bo->base.request);
+			free(old);
+			bo->base.refcnt = 1;
 		} else {
-			__kgem_bo_init(&bo->base, handle, alloc);
-			bo->base.reusable = false;
-			bo->base.sync = true;
-			bo->need_io = 0;
+			if (!__kgem_bo_init(&bo->base,
+					    gem_create(kgem->fd, alloc),
+					    alloc)) {
+				free(bo);
+				return NULL;
+			}
 		}
+		bo->need_io = true;
+	} else {
+		__kgem_bo_init(&bo->base, handle, alloc);
+		bo->base.reusable = false;
+		bo->base.sync = true;
+		bo->need_io = 0;
+	}
 
-		bo->alloc = alloc;
-		bo->used = size;
-		bo->write = write;
+	bo->alloc = alloc;
+	bo->used = size;
+	bo->write = write;
+	offset = 0;
 
-		list_add(&bo->base.list, &kgem->partial);
-		DBG(("%s(size=%d) new handle=%d\n",
-		     __FUNCTION__, alloc, bo->base.handle));
-	}
+	list_add(&bo->base.list, &kgem->partial);
+	DBG(("%s(size=%d) new handle=%d\n",
+	     __FUNCTION__, alloc, bo->base.handle));
 
+done:
 	*ret = (char *)(bo+1) + offset;
 	return kgem_create_proxy(&bo->base, offset, size);
 }
commit 6e7a0c86419bf6c928837f592784333c25d8b27b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jul 5 23:05:37 2011 +0100

    sna: Discard unused partial buffers
    
    If we allocate a partial buffer and then fallback for the operation, the
    buffer would remain on the partial list waiting for another user.
    Discard any unused partials at the next batch submission or expiration
    point.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 87acb49..46380a8 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -686,8 +686,15 @@ static void kgem_finish_partials(struct kgem *kgem)
 	struct kgem_partial_bo *bo, *next;
 
 	list_for_each_entry_safe(bo, next, &kgem->partial, base.list) {
-		if (!bo->base.exec)
+		if (!bo->base.exec) {
+			if (bo->base.refcnt == 1) {
+				DBG(("%s: discarding unused partial array: %d/%d\n",
+				     __FUNCTION__, bo->used, bo->alloc));
+				goto unref;
+			}
+
 			continue;
+		}
 
 		if (bo->write && bo->need_io) {
 			DBG(("%s: handle=%d, uploading %d/%d\n",
@@ -697,6 +704,7 @@ static void kgem_finish_partials(struct kgem *kgem)
 			bo->need_io = 0;
 		}
 
+unref:
 		list_del(&bo->base.list);
 		kgem_bo_unref(kgem, &bo->base);
 	}
@@ -967,6 +975,21 @@ void kgem_throttle(struct kgem *kgem)
 	}
 }
 
+static void kgem_expire_partial(struct kgem *kgem)
+{
+	struct kgem_partial_bo *bo, *next;
+
+	list_for_each_entry_safe(bo, next, &kgem->partial, base.list) {
+		if (bo->base.refcnt > 1)
+			continue;
+
+		DBG(("%s: discarding unused partial array: %d/%d\n",
+		     __FUNCTION__, bo->used, bo->alloc));
+		list_del(&bo->base.list);
+		kgem_bo_unref(kgem, &bo->base);
+	}
+}
+
 bool kgem_expire_cache(struct kgem *kgem)
 {
 	time_t now, expire;
@@ -979,6 +1002,8 @@ bool kgem_expire_cache(struct kgem *kgem)
 	if (kgem->wedged)
 		kgem_cleanup(kgem);
 
+	kgem_expire_partial(kgem);
+
 	time(&now);
 	expire = 0;
 


More information about the xorg-commit mailing list