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

Chris Wilson ickle at kemper.freedesktop.org
Mon Aug 29 08:48:42 PDT 2011


 src/sna/kgem.c      |   64 +++++++++++++++++++++++++++++++++++++++++++++++-----
 src/sna/kgem.h      |    1 
 src/sna/sna_accel.c |    2 +
 3 files changed, 62 insertions(+), 5 deletions(-)

New commits:
commit aafe03d3d1cfd5cbdf345cd51436de268ac27b6f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 29 16:47:48 2011 +0100

    sna: Retain the GTT space used for an upload buffer
    
    In order to retain the GTT space without keeping hold of the memory used
    for the upload buffer, we have to create a new bo and copy the relevant
    details across.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index ef829fe..947fac4 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -701,15 +701,29 @@ static void kgem_finish_partials(struct kgem *kgem)
 			continue;
 		}
 
+		list_del(&bo->base.list);
+
 		if (bo->write && bo->need_io) {
 			DBG(("%s: handle=%d, uploading %d/%d\n",
 			     __FUNCTION__, bo->base.handle, bo->used, bo->alloc));
 			gem_write(kgem->fd, bo->base.handle,
 				  0, bo->used, bo+1);
 			bo->need_io = 0;
+
+			/* transfer the handle to a minimum bo */
+			if (bo->base.refcnt == 1) {
+				struct kgem_bo *base = malloc(sizeof(*base));
+				if (base) {
+					memcpy(base, &bo->base, sizeof (*base));
+					list_init(&base->list);
+					list_replace(&bo->base.request,
+						     &base->request);
+					free(bo);
+					bo = (struct kgem_partial_bo *)base;
+				}
+			}
 		}
 
-		list_del(&bo->base.list);
 		kgem_bo_unref(kgem, &bo->base);
 	}
 }
commit 28c8c5ca14c5b4eab7e2dc58c87050c1019037bb
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 29 16:27:35 2011 +0100

    sna: Free the buffers immediately upon release
    
    They do not appear to have been leaked per-se, but we end up
    accumulating the unused buffers. A more complicated solution would be to
    reallocate the handle for retained buffers so that the GTT region can be
    reused.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=39184
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index dcc3569..ef829fe 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -692,7 +692,10 @@ static void kgem_finish_partials(struct kgem *kgem)
 			if (bo->base.refcnt == 1) {
 				DBG(("%s: discarding unused partial array: %d/%d\n",
 				     __FUNCTION__, bo->used, bo->alloc));
-				goto unref;
+
+				list_del(&bo->base.list);
+				gem_close(kgem->fd, bo->base.handle);
+				free(bo);
 			}
 
 			continue;
@@ -706,7 +709,6 @@ static void kgem_finish_partials(struct kgem *kgem)
 			bo->need_io = 0;
 		}
 
-unref:
 		list_del(&bo->base.list);
 		kgem_bo_unref(kgem, &bo->base);
 	}
@@ -1840,7 +1842,6 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 		}
 	}
 
-
 	alloc = (flags & KGEM_BUFFER_LAST) ? 4096 : 32 * 1024;
 	alloc = ALIGN(size, alloc);
 
@@ -1879,10 +1880,10 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
 		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->base.reusable = false;
 
 	bo->alloc = alloc;
 	bo->used = size;
commit 4f2fc00944272243af343a8b99f6eb8e0dfda006
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Aug 29 15:14:41 2011 +0100

    sna: Cleanup up the cache upon close
    
    To help with leak-chasing under valgrind.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 061ca74..dcc3569 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1064,6 +1064,45 @@ bool kgem_expire_cache(struct kgem *kgem)
 	(void)size;
 }
 
+void kgem_cleanup_cache(struct kgem *kgem)
+{
+	struct kgem_bo *bo;
+	int i;
+
+	/* sync to the most recent request */
+	if (!list_is_empty(&kgem->requests)) {
+		struct kgem_request *rq;
+		struct drm_i915_gem_set_domain set_domain;
+
+		rq = list_first_entry(&kgem->requests,
+				      struct kgem_request,
+				      list);
+
+		set_domain.handle = rq->bo->handle;
+		set_domain.read_domains = I915_GEM_DOMAIN_GTT;
+		set_domain.write_domain = I915_GEM_DOMAIN_GTT;
+		drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain);
+	}
+
+	kgem_retire(kgem);
+	kgem_cleanup(kgem);
+	kgem_expire_partial(kgem);
+
+	for (i = 0; i < ARRAY_SIZE(kgem->inactive); i++) {
+		while (!list_is_empty(&kgem->inactive[i])) {
+			bo = list_last_entry(&kgem->inactive[i],
+					     struct kgem_bo, list);
+
+			gem_close(kgem->fd, bo->handle);
+			list_del(&bo->list);
+			free(bo);
+		}
+	}
+
+	kgem->need_purge = false;
+	kgem->need_expire = false;
+}
+
 static struct kgem_bo *
 search_linear_cache(struct kgem *kgem, int size, bool active)
 {
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index 9da4740..6f5035e 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -327,6 +327,7 @@ void kgem_buffer_sync(struct kgem *kgem, struct kgem_bo *bo);
 
 void kgem_throttle(struct kgem *kgem);
 bool kgem_expire_cache(struct kgem *kgem);
+void kgem_cleanup_cache(struct kgem *kgem);
 
 #if HAS_EXTRA_DEBUG
 void __kgem_batch_debug(struct kgem *kgem, uint32_t nbatch);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 8a7cec2..7edff77 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -3400,6 +3400,8 @@ void sna_accel_close(struct sna *sna)
 	sna_gradients_close(sna);
 
 	DeleteCallback(&FlushCallback, sna_accel_flush_callback, sna);
+
+	kgem_cleanup_cache(&sna->kgem);
 }
 
 static void sna_accel_throttle(struct sna *sna)


More information about the xorg-commit mailing list