Using a VMA on more than one timeline concurrently is the exception rather than the rule (using it concurrently on multiple engines). As we expect to only use one active tracker, store the most recently used tracker inside the i915_vma itself and only fallback to the radixtree if we need a second or more concurrent active trackers. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_vma.c | 46 ++++++++++++++++++++++++++------- drivers/gpu/drm/i915/i915_vma.h | 1 + 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 6bed7a2924cd..0158d46e38ed 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -88,6 +88,12 @@ i915_vma_retire(struct i915_gem_active *base, struct i915_request *rq) __i915_vma_retire(vma, rq); } +static void +i915_vma_last_retire(struct i915_gem_active *base, struct i915_request *rq) +{ + __i915_vma_retire(container_of(base, struct i915_vma, last_active), rq); +} + static struct i915_vma * vma_create(struct drm_i915_gem_object *obj, struct i915_address_space *vm, @@ -105,6 +111,7 @@ vma_create(struct drm_i915_gem_object *obj, INIT_RADIX_TREE(&vma->active_rt, GFP_KERNEL); + init_request_active(&vma->last_active, i915_vma_last_retire); init_request_active(&vma->last_fence, NULL); vma->vm = vm; vma->ops = &vm->vma_ops; @@ -870,8 +877,14 @@ static void export_fence(struct i915_vma *vma, static struct i915_gem_active *lookup_active(struct i915_vma *vma, u64 idx) { struct i915_vma_active *active; + struct i915_request *old; int err; + old = i915_gem_active_raw(&vma->last_active, + &vma->vm->i915->drm.struct_mutex); + if (!old || old->fence.context == idx) + goto out; + /* * XXX Note that the radix_tree uses unsigned longs for it indices, * a problem for us on i386 with 32bit longs. However, the likelihood @@ -879,13 +892,9 @@ static struct i915_gem_active *lookup_active(struct i915_vma *vma, u64 idx) * and further reduced by that both timelines must be active * simultaneously to confuse us. */ - active = radix_tree_lookup(&vma->active_rt, idx); - if (likely(active)) { - GEM_BUG_ON(i915_gem_active_isset(&active->base) && - idx != i915_gem_active_peek(&active->base, - &vma->vm->i915->drm.struct_mutex)->fence.context); - return &active->base; - } + active = radix_tree_lookup(&vma->active_rt, old->fence.context); + if (likely(active)) + goto replace; active = kmalloc(sizeof(*active), GFP_KERNEL); if (unlikely(!active)) @@ -894,13 +903,27 @@ static struct i915_gem_active *lookup_active(struct i915_vma *vma, u64 idx) init_request_active(&active->base, i915_vma_retire); active->vma = vma; - err = radix_tree_insert(&vma->active_rt, idx, active); + err = radix_tree_insert(&vma->active_rt, old->fence.context, active); if (unlikely(err)) { kfree(active); return ERR_PTR(err); } - return &active->base; +replace: + if (i915_gem_active_isset(&active->base)) { + GEM_BUG_ON(old->fence.context != + i915_gem_active_raw(&active->base, + &vma->vm->i915->drm.struct_mutex)->fence.context); + __list_del_entry(&active->base.link); + vma->active_count--; + GEM_BUG_ON(!vma->active_count); + } + GEM_BUG_ON(list_empty(&vma->last_active.link)); + list_replace_init(&vma->last_active.link, &active->base.link); + active->base.request = fetch_and_zero(&vma->last_active.request); + +out: + return &vma->last_active; } int i915_vma_move_to_active(struct i915_vma *vma, @@ -981,6 +1004,11 @@ int i915_vma_unbind(struct i915_vma *vma) */ __i915_vma_pin(vma); + ret = i915_gem_active_retire(&vma->last_active, + &vma->vm->i915->drm.struct_mutex); + if (ret) + goto unpin; + rcu_read_lock(); radix_tree_for_each_slot(slot, &vma->active_rt, &iter, 0) { struct i915_vma_active *active = diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 94fdf4917e95..1d3080603a18 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -97,6 +97,7 @@ struct i915_vma { unsigned int active_count; struct radix_tree_root active_rt; + struct i915_gem_active last_active; struct i915_gem_active last_fence; /** -- 2.17.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx