diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-05 23:05:37 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-05 23:36:09 +0100 |
commit | 6e7a0c86419bf6c928837f592784333c25d8b27b (patch) | |
tree | a23cf00be770900ee8d3e8f99dbcefb223a3dd3b | |
parent | 3b5971bd2359383cb8326702d80e03bc15d34c69 (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.c | 27 |
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; |