drm/i915: Remove toplevel struct_mutex locking from debugfs/i915_drop_caches
authorChris Wilson <chris@chris-wilson.co.uk>
Wed, 24 May 2017 16:26:53 +0000 (17:26 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 30 May 2017 10:46:23 +0000 (11:46 +0100)
I have a plan to write a quick test to exercise concurrent usage of
i915_gem_shrink(), the simplest way looks to be to have multiple threads
using debugfs/i915_drop_caches. However, we currently take one lock over
the entire function, serialising the calls into i915_gem_shrink() so
reduce the lock coverage.

Testcase: igt/gem_shrink/reclaim
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170524162653.5446-1-chris@chris-wilson.co.uk
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
drivers/gpu/drm/i915/i915_debugfs.c

index 7e0816ccdc217debbd597cc213d2c62129a152d8..3b088685a553a4ecc0cb603391f805bd263f0608 100644 (file)
@@ -4289,26 +4289,27 @@ i915_drop_caches_set(void *data, u64 val)
 {
        struct drm_i915_private *dev_priv = data;
        struct drm_device *dev = &dev_priv->drm;
-       int ret;
+       int ret = 0;
 
        DRM_DEBUG("Dropping caches: 0x%08llx\n", val);
 
        /* No need to check and wait for gpu resets, only libdrm auto-restarts
         * on ioctls on -EAGAIN. */
-       ret = mutex_lock_interruptible(&dev->struct_mutex);
-       if (ret)
-               return ret;
-
-       if (val & DROP_ACTIVE) {
-               ret = i915_gem_wait_for_idle(dev_priv,
-                                            I915_WAIT_INTERRUPTIBLE |
-                                            I915_WAIT_LOCKED);
+       if (val & (DROP_ACTIVE | DROP_RETIRE)) {
+               ret = mutex_lock_interruptible(&dev->struct_mutex);
                if (ret)
-                       goto unlock;
-       }
+                       return ret;
 
-       if (val & DROP_RETIRE)
-               i915_gem_retire_requests(dev_priv);
+               if (val & DROP_ACTIVE)
+                       ret = i915_gem_wait_for_idle(dev_priv,
+                                                    I915_WAIT_INTERRUPTIBLE |
+                                                    I915_WAIT_LOCKED);
+
+               if (val & DROP_RETIRE)
+                       i915_gem_retire_requests(dev_priv);
+
+               mutex_unlock(&dev->struct_mutex);
+       }
 
        lockdep_set_current_reclaim_state(GFP_KERNEL);
        if (val & DROP_BOUND)
@@ -4321,9 +4322,6 @@ i915_drop_caches_set(void *data, u64 val)
                i915_gem_shrink_all(dev_priv);
        lockdep_clear_current_reclaim_state();
 
-unlock:
-       mutex_unlock(&dev->struct_mutex);
-
        if (val & DROP_FREED) {
                synchronize_rcu();
                i915_gem_drain_freed_objects(dev_priv);