]> www.infradead.org Git - users/hch/misc.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)
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Mon, 7 Oct 2024 03:18:46 +0000 (06:18 +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>
(cherry picked from commit abc0742c79bdb3b164eacab24aea0916d2ec1cb5)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
drivers/gpu/drm/i915/display/intel_hdcp.c

index 6980b98792c212fe0ebcf58c6c025a843ef33c2d..377939de0ff4f2e230691b62b2f363507010044c 100644 (file)
@@ -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);
+
                }
        }