diff options
author | Dave Airlie <airlied@redhat.com> | 2015-06-15 10:34:28 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-06-25 11:57:23 +1000 |
commit | 6b8eeca65b18ae77e175cc2b6571731f0ee413bf (patch) | |
tree | df8de7144582b43d6e90024dc1a88fc873906499 /include/drm | |
parent | 8b72ce158cf0dba443e36fc66e0bb29c2580e0b6 (diff) | |
download | op-kernel-dev-6b8eeca65b18ae77e175cc2b6571731f0ee413bf.zip op-kernel-dev-6b8eeca65b18ae77e175cc2b6571731f0ee413bf.tar.gz |
drm/dp/mst: close deadlock in connector destruction.
I've only seen this once, and I failed to capture the
lockdep backtrace, but I did some investigations.
If we are calling into the MST layer from EDID probing,
we have the mode_config mutex held, if during that EDID
probing, the MST hub goes away, then we can get a deadlock
where the connector destruction function in the driver
tries to retake the mode config mutex.
This offloads connector destruction to a workqueue,
and avoid the subsequenct lock ordering issue.
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: stable@vger.kernel.org
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'include/drm')
-rw-r--r-- | include/drm/drm_crtc.h | 2 | ||||
-rw-r--r-- | include/drm/drm_dp_mst_helper.h | 4 |
2 files changed, 6 insertions, 0 deletions
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 3b4d8a4..57ca8cc 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -743,6 +743,8 @@ struct drm_connector { uint8_t num_h_tile, num_v_tile; uint8_t tile_h_loc, tile_v_loc; uint16_t tile_h_size, tile_v_size; + + struct list_head destroy_list; }; /** diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h index a250781..86d0b25 100644 --- a/include/drm/drm_dp_mst_helper.h +++ b/include/drm/drm_dp_mst_helper.h @@ -463,6 +463,10 @@ struct drm_dp_mst_topology_mgr { struct work_struct work; struct work_struct tx_work; + + struct list_head destroy_connector_list; + struct mutex destroy_connector_lock; + struct work_struct destroy_connector_work; }; int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, struct device *dev, struct drm_dp_aux *aux, int max_dpcd_transaction_bytes, int max_payloads, int conn_base_id); |