[Intel-gfx] [PATCH v3.1 3/3] drm/i915: Don't try to remove MST cleanly when force removed.

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Thu Aug 6 04:47:37 PDT 2015


Physically disconnecting a DP connector with an active MST stream
can lead to a kernel panic in intel_mst_disable_dp when calling
drm_dp_update_payload_part1. Examining the code it seems that the
port is freed while work to remove the connector is scheduled.

This probably means it's fine to skip call all the mst helper calls
and only attempt to disable the real encoder.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_dp_mst.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c
index 91ad17110c2f..19c9e49d74e0 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -110,6 +110,9 @@ static void intel_mst_disable_dp(struct intel_encoder *encoder)
 
 	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
 
+	if (!intel_mst->port)
+		return;
+
 	drm_dp_mst_reset_vcpi_slots(&intel_dp->mst_mgr, intel_mst->port);
 
 	ret = drm_dp_update_payload_part1(&intel_dp->mst_mgr);
@@ -126,12 +129,14 @@ static void intel_mst_post_disable_dp(struct intel_encoder *encoder)
 
 	DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
 
-	/* this can fail */
-	drm_dp_check_act_status(&intel_dp->mst_mgr);
-	/* and this can also fail */
-	drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+	if (intel_mst->port) {
+		/* this can fail */
+		drm_dp_check_act_status(&intel_dp->mst_mgr);
+		/* and this can also fail */
+		drm_dp_update_payload_part2(&intel_dp->mst_mgr);
 
-	drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, intel_mst->port);
+		drm_dp_mst_deallocate_vcpi(&intel_dp->mst_mgr, intel_mst->port);
+	}
 
 	intel_dp->active_mst_links--;
 	intel_mst->port = NULL;
@@ -471,9 +476,13 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
 	/* need to nuke the connector */
 	drm_modeset_lock_all(dev);
 	if (connector->state->crtc) {
+		struct drm_encoder *encoder = connector->state->best_encoder;
+		struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
 		struct drm_mode_set set;
 		int ret;
 
+		intel_mst->port = NULL;
+
 		memset(&set, 0, sizeof(set));
 		set.crtc = connector->state->crtc,
 
-- 
2.1.0



More information about the Intel-gfx mailing list