OSDN Git Service

drm/i915: Handle locking better in i915_sink_crc.
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fri, 10 Nov 2017 11:34:58 +0000 (12:34 +0100)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Mon, 13 Nov 2017 09:04:30 +0000 (10:04 +0100)
Lock the bare minimum, instead of the entire world, and
use interruptible locking because we can.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171110113503.16253-6-maarten.lankhorst@linux.intel.com
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_debugfs.c

index 533ba09..cb77aea 100644 (file)
@@ -2735,39 +2735,63 @@ static int i915_sink_crc(struct seq_file *m, void *data)
        struct intel_connector *connector;
        struct drm_connector_list_iter conn_iter;
        struct intel_dp *intel_dp = NULL;
+       struct drm_modeset_acquire_ctx ctx;
        int ret;
        u8 crc[6];
 
-       drm_modeset_lock_all(dev);
+       drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
+
        drm_connector_list_iter_begin(dev, &conn_iter);
+
        for_each_intel_connector_iter(connector, &conn_iter) {
                struct drm_crtc *crtc;
+               struct drm_connector_state *state;
 
-               if (!connector->base.state->best_encoder)
+               if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
                        continue;
 
-               crtc = connector->base.state->crtc;
-               if (!crtc->state->active)
+retry:
+               ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
+               if (ret)
+                       goto err;
+
+               state = connector->base.state;
+               if (!state->best_encoder)
                        continue;
 
-               if (connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
+               crtc = state->crtc;
+               ret = drm_modeset_lock(&crtc->mutex, &ctx);
+               if (ret)
+                       goto err;
+
+               if (!crtc->state->active)
                        continue;
 
-               intel_dp = enc_to_intel_dp(connector->base.state->best_encoder);
+               intel_dp = enc_to_intel_dp(state->best_encoder);
 
                ret = intel_dp_sink_crc(intel_dp, crc);
                if (ret)
-                       goto out;
+                       goto err;
 
                seq_printf(m, "%02x%02x%02x%02x%02x%02x\n",
                           crc[0], crc[1], crc[2],
                           crc[3], crc[4], crc[5]);
                goto out;
+
+err:
+               if (ret == -EDEADLK) {
+                       ret = drm_modeset_backoff(&ctx);
+                       if (!ret)
+                               goto retry;
+               }
+               goto out;
        }
        ret = -ENODEV;
 out:
        drm_connector_list_iter_end(&conn_iter);
-       drm_modeset_unlock_all(dev);
+       drm_modeset_drop_locks(&ctx);
+       drm_modeset_acquire_fini(&ctx);
+
        return ret;
 }