summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-07-05 23:05:37 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2011-07-05 23:36:09 +0100
commit6e7a0c86419bf6c928837f592784333c25d8b27b (patch)
treea23cf00be770900ee8d3e8f99dbcefb223a3dd3b
parent3b5971bd2359383cb8326702d80e03bc15d34c69 (diff)
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@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 87acb49b..46380a8a 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;