summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-03-13 21:29:57 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-03-13 22:00:05 +0000
commit0acec1685328b1dd9dffa804a27a122fc6e4225a (patch)
treeaed596cc6ddfcd80955596615bb82c0331bba8b4
parent06b28d541bdf2607edc2eb476919b28e747885d8 (diff)
sna: Defer the release of the upload buffer cache till retirement
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c49
-rw-r--r--src/sna/sna_accel.c1
2 files changed, 33 insertions, 17 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index cee45139..72751f33 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1238,7 +1238,26 @@ static void kgem_retire_partials(struct kgem *kgem)
assert(next->base.list.prev == &bo->base.list);
assert(bo->base.io);
- if (bo->base.refcnt != 1 || bo->base.rq)
+ if (bo->base.rq)
+ continue;
+
+ DBG(("%s: releasing upload cache for handle=%d? %d\n",
+ __FUNCTION__, bo->base.handle, !list_is_empty(&bo->base.vma)));
+ while (!list_is_empty(&bo->base.vma)) {
+ struct kgem_bo *cached;
+
+ cached = list_first_entry(&bo->base.vma, struct kgem_bo, vma);
+ assert(cached->proxy == &bo->base);
+ list_del(&cached->vma);
+
+ assert(*(struct kgem_bo **)cached->map == cached);
+ *(struct kgem_bo **)cached->map = NULL;
+ cached->map = NULL;
+
+ kgem_bo_destroy(kgem, cached);
+ }
+
+ if (bo->base.refcnt != 1)
continue;
DBG(("%s: handle=%d, used %d/%d\n", __FUNCTION__,
@@ -1256,6 +1275,8 @@ static void kgem_retire_partials(struct kgem *kgem)
bo->base.needs_flush = false;
bo->used = 0;
+ DBG(("%s: transferring partial handle=%d to inactive\n",
+ __FUNCTION__, bo->base.handle));
list_move_tail(&bo->base.list, &kgem->inactive_partials);
bubble_sort_partial(&kgem->inactive_partials, bo);
}
@@ -1381,9 +1402,7 @@ static void kgem_commit(struct kgem *kgem)
{
struct kgem_request *rq = kgem->next_request;
struct kgem_bo *bo, *next;
- struct list release;
- list_init(&release);
list_for_each_entry_safe(bo, next, &rq->buffers, request) {
assert(next->request.prev == &bo->request);
@@ -1392,7 +1411,7 @@ static void kgem_commit(struct kgem *kgem)
bo->dirty, bo->needs_flush, (unsigned)bo->exec->offset));
assert(!bo->purged);
- assert(bo->proxy || bo->rq == rq);
+ assert(bo->rq == rq || (bo->proxy->rq == rq));
bo->presumed_offset = bo->exec->offset;
bo->exec = NULL;
@@ -1411,20 +1430,8 @@ static void kgem_commit(struct kgem *kgem)
list_del(&bo->request);
bo->rq = NULL;
bo->exec = &_kgem_dummy_exec;
- if (bo->map)
- list_add_tail(&bo->request, &release);
}
}
- while (!list_is_empty(&release)) {
- bo = list_first_entry(&release, struct kgem_bo, request);
- DBG(("%s: releasing upload cache, handle=%d\n",
- __FUNCTION__, bo->handle));
- list_del(&bo->request);
- assert(*(struct kgem_bo **)bo->map == bo);
- *(struct kgem_bo **)bo->map = NULL;
- bo->map = NULL;
- kgem_bo_destroy(kgem, bo);
- }
if (rq == &_kgem_static_request) {
struct drm_i915_gem_set_domain set_domain;
@@ -2869,11 +2876,12 @@ void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
__FUNCTION__, bo->handle, bo->proxy != NULL));
if (bo->proxy) {
+ _list_del(&bo->vma);
+ _list_del(&bo->request);
if (bo->io && (bo->exec == NULL || bo->proxy->rq == NULL))
_kgem_bo_delete_partial(kgem, bo);
kgem_bo_unref(kgem, bo->proxy);
kgem_bo_binding_free(kgem, bo);
- _list_del(&bo->request);
free(bo);
return;
}
@@ -3468,6 +3476,11 @@ struct kgem_bo *kgem_create_buffer(struct kgem *kgem,
}
}
+ if (bo->used && bo->base.rq == NULL && bo->base.refcnt == 1) {
+ bo->used = 0;
+ bubble_sort_partial(&kgem->active_partials, bo);
+ }
+
if (bo->used + size <= bytes(&bo->base)) {
DBG(("%s: reusing partial buffer? used=%d + size=%d, total=%d\n",
__FUNCTION__, bo->used, size, bytes(&bo->base)));
@@ -3895,6 +3908,8 @@ void kgem_proxy_bo_attach(struct kgem_bo *bo,
{
DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle));
assert(bo->map == NULL);
+ assert(bo->proxy);
+ list_add(&bo->vma, &bo->proxy->vma);
bo->map = ptr;
*ptr = kgem_bo_reference(bo);
}
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c9016a19..b0b55a49 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -11822,6 +11822,7 @@ static void sna_accel_inactive(struct sna *sna)
inactive);
assert((priv->create & KGEM_CAN_CREATE_LARGE) == 0);
assert(priv->gpu_bo);
+ assert(!priv->gpu_bo->proxy);
/* XXX Rather than discarding the GPU buffer here, we
* could mark it purgeable and allow the shrinker to