Commit 51a575d9 authored by Chris Wilson's avatar Chris Wilson

drm/i915: Retire an active batch pool object rather than allocate new

Since obj->active_count is only updated upon retirement, if we see an
active object in the batch pool, double check that is still active
before deciding to allocate a new object.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170316132006.7976-3-chris@chris-wilson.co.ukReviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent 92a0256e
...@@ -96,8 +96,7 @@ struct drm_i915_gem_object * ...@@ -96,8 +96,7 @@ struct drm_i915_gem_object *
i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
size_t size) size_t size)
{ {
struct drm_i915_gem_object *obj = NULL; struct drm_i915_gem_object *obj;
struct drm_i915_gem_object *tmp;
struct list_head *list; struct list_head *list;
int n, ret; int n, ret;
...@@ -112,31 +111,29 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, ...@@ -112,31 +111,29 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool,
n = ARRAY_SIZE(pool->cache_list) - 1; n = ARRAY_SIZE(pool->cache_list) - 1;
list = &pool->cache_list[n]; list = &pool->cache_list[n];
list_for_each_entry(tmp, list, batch_pool_link) { list_for_each_entry(obj, list, batch_pool_link) {
/* The batches are strictly LRU ordered */ /* The batches are strictly LRU ordered */
if (i915_gem_object_is_active(tmp)) if (i915_gem_object_is_active(obj)) {
break; if (!reservation_object_test_signaled_rcu(obj->resv,
true))
break;
GEM_BUG_ON(!reservation_object_test_signaled_rcu(tmp->resv, i915_gem_retire_requests(pool->engine->i915);
true)); GEM_BUG_ON(i915_gem_object_is_active(obj));
}
if (tmp->base.size >= size) { GEM_BUG_ON(!reservation_object_test_signaled_rcu(obj->resv,
/* Clear the set of shared fences early */ true));
reservation_object_lock(tmp->resv, NULL);
reservation_object_add_excl_fence(tmp->resv, NULL);
reservation_object_unlock(tmp->resv);
obj = tmp; if (obj->base.size >= size)
break; goto found;
}
} }
if (obj == NULL) { obj = i915_gem_object_create_internal(pool->engine->i915, size);
obj = i915_gem_object_create_internal(pool->engine->i915, size); if (IS_ERR(obj))
if (IS_ERR(obj)) return obj;
return obj;
}
found:
ret = i915_gem_object_pin_pages(obj); ret = i915_gem_object_pin_pages(obj);
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment