intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Sean Paul <sean@poorly.run>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Cc: daniel.vetter@ffwll.ch, Sean Paul <seanpaul@chromium.org>
Subject: [Intel-gfx] [PATCH v3 07/12] drm/i915: Protect workers against disappearing connectors
Date: Fri, 17 Jan 2020 14:30:58 -0500	[thread overview]
Message-ID: <20200117193103.156821-8-sean@poorly.run> (raw)
In-Reply-To: <20200117193103.156821-1-sean@poorly.run>

From: Sean Paul <seanpaul@chromium.org>

This patch adds some protection against connectors being destroyed
before the HDCP workers are finished.

For check_work, we do a synchronous cancel after the connector is
unregistered which will ensure that it is finished before destruction.

In the case of prop_work, we can't do a synchronous wait since it needs
to take connection_mutex which could cause deadlock. Instead, we'll take
a reference on the connector when scheduling prop_work and give it up
once we're done.

Reviewed-by: Ramalingam C <ramalingam.c@intel.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20191212190230.188505-8-sean@poorly.run #v2

Changes in v2:
- Added to the set
Changes in v3:
- Change the WARN_ON condition in intel_hdcp_cleanup to allow for
  initializing connectors as well
---
 drivers/gpu/drm/i915/display/intel_hdcp.c | 43 ++++++++++++++++++++---
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 798e7e1a19fc..fabacfb1b644 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -863,8 +863,10 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
 		return;
 
 	hdcp->value = value;
-	if (update_property)
+	if (update_property) {
+		drm_connector_get(&connector->base);
 		schedule_work(&hdcp->prop_work);
+	}
 }
 
 /* Implements Part 3 of the HDCP authorization procedure */
@@ -954,6 +956,8 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 
 	mutex_unlock(&hdcp->mutex);
 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+	drm_connector_put(&connector->base);
 }
 
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port)
@@ -1802,6 +1806,9 @@ static void intel_hdcp_check_work(struct work_struct *work)
 					       check_work);
 	struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
 
+	if (drm_connector_is_unregistered(&connector->base))
+		return;
+
 	if (!intel_hdcp2_check_link(connector))
 		schedule_delayed_work(&hdcp->check_work,
 				      DRM_HDCP2_CHECK_PERIOD_MS);
@@ -2076,12 +2083,38 @@ void intel_hdcp_component_fini(struct drm_i915_private *dev_priv)
 
 void intel_hdcp_cleanup(struct intel_connector *connector)
 {
-	if (!connector->hdcp.shim)
+	struct intel_hdcp *hdcp = &connector->hdcp;
+
+	if (!hdcp->shim)
 		return;
 
-	mutex_lock(&connector->hdcp.mutex);
-	kfree(connector->hdcp.port_data.streams);
-	mutex_unlock(&connector->hdcp.mutex);
+	/*
+	 * If the connector is registered, it's possible userspace could kick
+	 * off another HDCP enable, which would re-spawn the workers.
+	 */
+	WARN_ON(connector->base.registration_state == DRM_CONNECTOR_REGISTERED);
+
+	/*
+	 * Now that the connector is not registered, check_work won't be run,
+	 * but cancel any outstanding instances of it
+	 */
+	cancel_delayed_work_sync(&hdcp->check_work);
+
+	/*
+	 * We don't cancel prop_work in the same way as check_work since it
+	 * requires connection_mutex which could be held while calling this
+	 * function. Instead, we rely on the connector references grabbed before
+	 * scheduling prop_work to ensure the connector is alive when prop_work
+	 * is run. So if we're in the destroy path (which is where this
+	 * function should be called), we're "guaranteed" that prop_work is not
+	 * active (tl;dr This Should Never Happen).
+	 */
+	WARN_ON(work_pending(&hdcp->prop_work));
+
+	mutex_lock(&hdcp->mutex);
+	kfree(hdcp->port_data.streams);
+	hdcp->shim = NULL;
+	mutex_unlock(&hdcp->mutex);
 }
 
 void intel_hdcp_atomic_check(struct drm_connector *connector,
-- 
Sean Paul, Software Engineer, Google / Chromium OS

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2020-01-17 19:31 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-17 19:30 [Intel-gfx] [PATCH v3 00/12] drm/i915: Add support for HDCP 1.4 over MST connectors Sean Paul
2020-01-17 19:30 ` [Intel-gfx] [PATCH v3 01/12] drm/i915: Fix sha_text population code Sean Paul
2020-01-19 15:26   ` Sasha Levin
2020-01-17 19:30 ` [Intel-gfx] [PATCH v3 02/12] drm/i915: Clear the repeater bit on HDCP disable Sean Paul
2020-01-19 15:26   ` Sasha Levin
2020-01-17 19:30 ` [Intel-gfx] [PATCH v3 03/12] drm/i915: WARN if HDCP signalling is enabled upon disable Sean Paul
2020-01-17 19:30 ` [Intel-gfx] [PATCH v3 04/12] drm/i915: Intercept Aksv writes in the aux hooks Sean Paul
2020-01-17 19:30 ` [Intel-gfx] [PATCH v3 05/12] drm/i915: Use the cpu_transcoder in intel_hdcp to toggle HDCP signalling Sean Paul
2020-01-17 19:30 ` [Intel-gfx] [PATCH v3 06/12] drm/i915: Factor out hdcp->value assignments Sean Paul
2020-01-17 19:30 ` Sean Paul [this message]
2020-01-17 19:30 ` [Intel-gfx] [PATCH v3 08/12] drm/i915: Don't fully disable HDCP on a port if multiple pipes are using it Sean Paul
2020-02-02 19:03   ` Ramalingam C
2020-02-18 22:07     ` Sean Paul
2020-01-17 19:31 ` [Intel-gfx] [PATCH v3 09/12] drm/i915: Support DP MST in enc_to_dig_port() function Sean Paul
2020-01-17 19:31 ` [Intel-gfx] [PATCH v3 10/12] drm/i915: Use ddi_update_pipe in intel_dp_mst Sean Paul
2020-01-17 19:31 ` [Intel-gfx] [PATCH v3 11/12] drm/i915: Factor out HDCP shim functions from dp for use by dp_mst Sean Paul
2020-01-17 19:31 ` [Intel-gfx] [PATCH v3 12/12] drm/i915: Add HDCP 1.4 support for MST connectors Sean Paul
2020-01-18  2:08 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915: Add support for HDCP 1.4 over MST connectors (rev3) Patchwork
2020-01-18  3:18 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-01-18  3:18 ` [Intel-gfx] ✗ Fi.CI.BUILD: warning " Patchwork
2020-01-20 19:46 ` [Intel-gfx] ✓ Fi.CI.IGT: success " Patchwork
2020-01-27 14:06 ` [Intel-gfx] [PATCH v3 00/12] drm/i915: Add support for HDCP 1.4 over MST connectors Sean Paul

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200117193103.156821-8-sean@poorly.run \
    --to=sean@poorly.run \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=seanpaul@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).