summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2017-12-15 11:30:26 +0100
committerChristian Gmeiner <christian.gmeiner@gmail.com>2017-12-15 19:40:10 +0100
commit7d984e609470aa38d4c3f7d48e26fa763a03af13 (patch)
tree8e6704eff66f503f1908f61e79fd7fd74632858c
parent4f8e426884a51b6786459ea2505f1ce82a13a87c (diff)
etnaviv: fix BO cache to properly work with different flags
Currently if the oldest BO in a bucket has different flags than what we look for we'll miss the cache.Fix this by iterating over the cached BOs until we find the oldest one with matching flags. This improves the hit ratio for some of the buckets. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
-rw-r--r--etnaviv/etnaviv_bo_cache.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/etnaviv/etnaviv_bo_cache.c b/etnaviv/etnaviv_bo_cache.c
index 8924651f..6208230d 100644
--- a/etnaviv/etnaviv_bo_cache.c
+++ b/etnaviv/etnaviv_bo_cache.c
@@ -124,20 +124,32 @@ static int is_idle(struct etna_bo *bo)
static struct etna_bo *find_in_bucket(struct etna_bo_bucket *bucket, uint32_t flags)
{
- struct etna_bo *bo = NULL;
+ struct etna_bo *bo = NULL, *tmp;
pthread_mutex_lock(&table_lock);
- while (!LIST_IS_EMPTY(&bucket->list)) {
- bo = LIST_ENTRY(struct etna_bo, bucket->list.next, list);
- if (bo->flags == flags && is_idle(bo)) {
- list_del(&bo->list);
- break;
+ if (LIST_IS_EMPTY(&bucket->list))
+ goto out_unlock;
+
+ LIST_FOR_EACH_ENTRY_SAFE(bo, tmp, &bucket->list, list) {
+ /* skip BOs with different flags */
+ if (bo->flags != flags)
+ continue;
+
+ /* check if the first BO with matching flags is idle */
+ if (is_idle(bo)) {
+ list_delinit(&bo->list);
+ goto out_unlock;
}
- bo = NULL;
+ /* If the oldest BO is still busy, don't try younger ones */
break;
}
+
+ /* There was no matching buffer found */
+ bo = NULL;
+
+out_unlock:
pthread_mutex_unlock(&table_lock);
return bo;