Commit 4cc2718f authored by Jani Nikula's avatar Jani Nikula Committed by Joonas Lahtinen
Browse files

drm/i915/hdcp: fix connector refcounting



We acquire a connector reference before scheduling an HDCP prop work,
and expect the work function to release the reference.

However, if the work was already queued, it won't be queued multiple
times, and the reference is not dropped.

Release the reference immediately if the work was already queued.

Fixes: a6597faa ("drm/i915: Protect workers against disappearing connectors")
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Suraj Kandpal <suraj.kandpal@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: stable@vger.kernel.org # v5.10+
Reviewed-by: default avatarSuraj Kandpal <suraj.kandpal@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240924153022.2255299-1-jani.nikula@intel.com


Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
(cherry picked from commit abc0742c)
Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent 8cf0b939
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -1094,7 +1094,8 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
	hdcp->value = value;
	if (update_property) {
		drm_connector_get(&connector->base);
		queue_work(i915->unordered_wq, &hdcp->prop_work);
		if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
			drm_connector_put(&connector->base);
	}
}

@@ -2524,7 +2525,8 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
		mutex_lock(&hdcp->mutex);
		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
		drm_connector_get(&connector->base);
		queue_work(i915->unordered_wq, &hdcp->prop_work);
		if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
			drm_connector_put(&connector->base);
		mutex_unlock(&hdcp->mutex);
	}

@@ -2541,7 +2543,9 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
		 */
		if (!desired_and_not_enabled && !content_protection_type_changed) {
			drm_connector_get(&connector->base);
			queue_work(i915->unordered_wq, &hdcp->prop_work);
			if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
				drm_connector_put(&connector->base);

		}
	}