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>
main
Lucas Stach 2017-12-15 11:30:26 +01:00 committed by Christian Gmeiner
parent 4f8e426884
commit 7d984e6094
1 changed files with 19 additions and 7 deletions

View File

@ -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) 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); 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)) { if (LIST_IS_EMPTY(&bucket->list))
list_del(&bo->list); goto out_unlock;
break;
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; break;
} }
/* There was no matching buffer found */
bo = NULL;
out_unlock:
pthread_mutex_unlock(&table_lock); pthread_mutex_unlock(&table_lock);
return bo; return bo;