summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2018-02-19 22:06:31 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2018-02-20 09:10:41 +0000
commitc9c70471549a0f5956bb3da4fc2609cd567a809d (patch)
tree43b3cf1f1a463134233c1b616a2f2802e007439b /drivers/gpu/drm/i915/i915_gem.c
parentbe3fa66857051e2943960a06f8046e8445cdfe6e (diff)
downloadlinux-c9c70471549a0f5956bb3da4fc2609cd567a809d.tar.bz2
drm/i915: Track number of pending freed objects
During igt, we frequently call into the driver to reset both HW and driver state (idling the device, waiting for it to become idle and freeing off old objects) to ensure that we start each test/subtest/pass from known state. This process incurs an RCU barrier or two to ensure that any such pending frees are indeed flushed before we return. However, unconditionally waiting on the RCU barrier adds needless delay to many callers, which adds up to several seconds when repeated thousands of times. We can skip the rcu_barrier() if by tracking how many outstanding frees we have, we know there are none. The same path is used along suspend, where we may be able to save the unconditional RCU barrier. To put it into perspective with a completely meaningless microbenchmark, igt/gem_sync/idle is improved from 50ms to 30us on bdw. v2: Remove the extra synchronize_rcu() inside i915_drop_caches_set() Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com> Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180219220631.25001-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index f530cd247724..631a2db2bb6e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4758,6 +4758,9 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915,
kfree(obj->bit_17);
i915_gem_object_free(obj);
+ GEM_BUG_ON(!atomic_read(&i915->mm.free_count));
+ atomic_dec(&i915->mm.free_count);
+
if (on)
cond_resched();
}
@@ -4846,6 +4849,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)
* i915_gem_busy_ioctl(). For the corresponding synchronized
* lookup see i915_gem_object_lookup_rcu().
*/
+ atomic_inc(&to_i915(obj->base.dev)->mm.free_count);
call_rcu(&obj->rcu, __i915_gem_free_object_rcu);
}
@@ -5546,7 +5550,8 @@ err_out:
void i915_gem_load_cleanup(struct drm_i915_private *dev_priv)
{
i915_gem_drain_freed_objects(dev_priv);
- WARN_ON(!llist_empty(&dev_priv->mm.free_list));
+ GEM_BUG_ON(!llist_empty(&dev_priv->mm.free_list));
+ GEM_BUG_ON(atomic_read(&dev_priv->mm.free_count));
WARN_ON(dev_priv->mm.object_count);
mutex_lock(&dev_priv->drm.struct_mutex);