diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-18 16:59:15 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-12-18 17:38:05 +0000 |
commit | a0c0a3765ca348c74096fb157885da5b1258ee08 (patch) | |
tree | 86c57dc717a8821937df1ad6fe173ed55d7884ae | |
parent | 34efb7314612cedcda4f866bc33f3ad5b6929ae2 (diff) |
sna: Retire if the inactive vma list is empty
Try to recycle vma by first trying to populate the inactive list before
scanning for a vma bo to harvest.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 78 |
1 files changed, 42 insertions, 36 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 80ed7100..3033f5f7 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1709,43 +1709,45 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem, /* We presume that we will need to upload to this bo, * and so would prefer to have an active VMA. */ - list_for_each_entry(bo, &kgem->vma_inactive, vma) { - assert(bo->refcnt == 0); - assert(bo->map); - assert(bo->rq == NULL); - assert(list_is_empty(&bo->request)); + do { + list_for_each_entry(bo, &kgem->vma_inactive, vma) { + assert(bo->refcnt == 0); + assert(bo->map); + assert(bo->rq == NULL); + assert(list_is_empty(&bo->request)); + + if (size > bo->size || 2*size < bo->size) { + DBG(("inactive vma too small/large: %d < %d\n", + bo->size, size)); + continue; + } - if (size > bo->size || 2*size < bo->size) { - DBG(("inactive vma too small/large: %d < %d\n", - bo->size, size)); - continue; - } + if (bo->tiling != tiling || + (tiling != I915_TILING_NONE && bo->pitch != pitch)) { + DBG(("inactive vma with wrong tiling: %d < %d\n", + bo->tiling, tiling)); + continue; + } - if (bo->tiling != tiling || - (tiling != I915_TILING_NONE && bo->pitch != pitch)) { - DBG(("inactive vma with wrong tiling: %d < %d\n", - bo->tiling, tiling)); - continue; - } + bo->pitch = pitch; + list_del(&bo->list); - bo->pitch = pitch; - list_del(&bo->list); + if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { + kgem_bo_free(kgem, bo); + break; + } - if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) { - kgem_bo_free(kgem, bo); - break; + bo->delta = 0; + bo->unique_id = kgem_get_unique_id(kgem); + list_move_tail(&bo->vma, &kgem->vma_cache); + assert(bo->pitch); + DBG((" from inactive vma: pitch=%d, tiling=%d: handle=%d, id=%d\n", + bo->pitch, bo->tiling, bo->handle, bo->unique_id)); + assert(bo->reusable); + assert(bo->domain != DOMAIN_GPU && !kgem_busy(kgem, bo->handle)); + return kgem_bo_reference(bo); } - - bo->delta = 0; - bo->unique_id = kgem_get_unique_id(kgem); - list_move_tail(&bo->vma, &kgem->vma_cache); - assert(bo->pitch); - DBG((" from inactive vma: pitch=%d, tiling=%d: handle=%d, id=%d\n", - bo->pitch, bo->tiling, bo->handle, bo->unique_id)); - assert(bo->reusable); - assert(bo->domain != DOMAIN_GPU && !kgem_busy(kgem, bo->handle)); - return kgem_bo_reference(bo); - } + } while (kgem_retire(kgem)); goto skip_active_search; } @@ -2077,17 +2079,21 @@ static void kgem_trim_vma_cache(struct kgem *kgem) struct kgem_bo, vma); } - DBG(("%s: discarding %s vma cache for %d\n", - __FUNCTION__, IS_CPU_MAP(old->map) ? "CPU" : "GTT", - old->handle)); + DBG(("%s: discarding %s %s vma cache for %d\n", + __FUNCTION__, + list_is_empty(&kgem->vma_inactive) ? "cached" : "inactive", + IS_CPU_MAP(old->map) ? "CPU" : "GTT", old->handle)); assert(old->map); munmap(CPU_MAP(old->map), old->size); old->map = NULL; list_del(&old->vma); kgem->vma_count--; - if (old->rq == NULL && old->refcnt == 0) + if (old->rq == NULL && old->refcnt == 0) { + DBG(("%s: discarding unused vma bo handle=%d\n", + __FUNCTION__, old->handle)); kgem_bo_free(kgem, old); +} } } |