diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-03-16 13:19:53 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-03-17 17:57:20 +0000 |
commit | 51a575d957fcb2848babb7163cb6e44a028a29ae (patch) | |
tree | 6576b0f8f8abbf00f63983b678264709183dee3e /drivers/gpu/drm/i915/i915_gem_batch_pool.c | |
parent | 92a0256e9acf20ee3f0add61b5aa774bfdf214cc (diff) | |
download | op-kernel-dev-51a575d957fcb2848babb7163cb6e44a028a29ae.zip op-kernel-dev-51a575d957fcb2848babb7163cb6e44a028a29ae.tar.gz |
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: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20170316132006.7976-3-chris@chris-wilson.co.uk
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_batch_pool.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_batch_pool.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c index 99ceae7..41aa598 100644 --- a/drivers/gpu/drm/i915/i915_gem_batch_pool.c +++ b/drivers/gpu/drm/i915/i915_gem_batch_pool.c @@ -96,8 +96,7 @@ struct drm_i915_gem_object * i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, size_t size) { - struct drm_i915_gem_object *obj = NULL; - struct drm_i915_gem_object *tmp; + struct drm_i915_gem_object *obj; struct list_head *list; int n, ret; @@ -112,31 +111,29 @@ i915_gem_batch_pool_get(struct i915_gem_batch_pool *pool, n = ARRAY_SIZE(pool->cache_list) - 1; 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 */ - if (i915_gem_object_is_active(tmp)) - break; + if (i915_gem_object_is_active(obj)) { + if (!reservation_object_test_signaled_rcu(obj->resv, + true)) + break; - GEM_BUG_ON(!reservation_object_test_signaled_rcu(tmp->resv, - true)); + i915_gem_retire_requests(pool->engine->i915); + GEM_BUG_ON(i915_gem_object_is_active(obj)); + } - if (tmp->base.size >= size) { - /* Clear the set of shared fences early */ - reservation_object_lock(tmp->resv, NULL); - reservation_object_add_excl_fence(tmp->resv, NULL); - reservation_object_unlock(tmp->resv); + GEM_BUG_ON(!reservation_object_test_signaled_rcu(obj->resv, + true)); - obj = tmp; - break; - } + if (obj->base.size >= size) + goto found; } - if (obj == NULL) { - obj = i915_gem_object_create_internal(pool->engine->i915, size); - if (IS_ERR(obj)) - return obj; - } + obj = i915_gem_object_create_internal(pool->engine->i915, size); + if (IS_ERR(obj)) + return obj; +found: ret = i915_gem_object_pin_pages(obj); if (ret) return ERR_PTR(ret); |