]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/hdcp: fix connector refcounting
authorJani Nikula <jani.nikula@intel.com>
Tue, 24 Sep 2024 15:30:22 +0000 (18:30 +0300)
committerJani Nikula <jani.nikula@intel.com>
Wed, 2 Oct 2024 18:26:28 +0000 (21:26 +0300)
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: a6597faa2d59 ("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: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240924153022.2255299-1-jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_hdcp.c

index 00d4c9ac6c452c805762d69890f76e32059daa53..ed6aa87403e23728fdae7551c1e56b04ecb3f055 100644 (file)
@@ -1097,7 +1097,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);
        }
 }
 
@@ -2554,7 +2555,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);
        }
 
@@ -2571,7 +2573,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);
+
                }
        }