From: Chris Wilson Date: Thu, 16 Mar 2017 13:19:53 +0000 (+0000) Subject: drm/i915: Retire an active batch pool object rather than allocate new X-Git-Tag: Ubuntu-5.0.0-8.9~5006^2~28^2~4 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=51a575d957fcb2848babb7163cb6e44a028a29ae;p=mirror_ubuntu-disco-kernel.git 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 Link: http://patchwork.freedesktop.org/patch/msgid/20170316132006.7976-3-chris@chris-wilson.co.uk Reviewed-by: Joonas Lahtinen --- diff --git a/drivers/gpu/drm/i915/i915_gem_batch_pool.c b/drivers/gpu/drm/i915/i915_gem_batch_pool.c index 99ceae7855f8..41aa598c4f3b 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);