FAILED: patch "[PATCH] drm/dp_mst: Fix clearing payload state on topology disable" failed to apply to 5.6-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 8732fe46b20c951493bfc4dba0ad08efdf41de81 Mon Sep 17 00:00:00 2001
From: Lyude Paul <[email protected]>
Date: Wed, 22 Jan 2020 14:43:20 -0500
Subject: [PATCH] drm/dp_mst: Fix clearing payload state on topology disable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The issues caused by:
commit 64e62bdf04ab ("drm/dp_mst: Remove VCPI while disabling topology mgr")
Prompted me to take a closer look at how we clear the payload state in general when disabling the topology, and it turns out there's actually two subtle issues here.
The first is that we're not grabbing &mgr.payload_lock when clearing the payloads in drm_dp_mst_topology_mgr_set_mst(). Seeing as the canonical lock order is &mgr.payload_lock -> &mgr.lock (because we always want &mgr.lock to be the inner-most lock so topology validation always works), this makes perfect sense. It also means that -technically- there could be racing between someone calling drm_dp_mst_topology_mgr_set_mst() to disable the topology, along with a modeset occurring that's modifying the payload state at the same time.
The second is the more obvious issue that Wayne Lin discovered, that we're not clearing proposed_payloads when disabling the topology.
I actually can't see any obvious places where the racing caused by the first issue would break something, and it could be that some of our higher-level locks already prevent this by happenstance, but better safe then sorry. So, let's make it so that drm_dp_mst_topology_mgr_set_mst() first grabs &mgr.payload_lock followed by &mgr.lock so that we never race when modifying the payload state. Then, we also clear proposed_payloads to fix the original issue of enabling a new topology with a dirty payload state. This doesn't clear any of the drm_dp_vcpi structures, but those are getting destroyed along with the ports anyway.
Changes since v1:
* Use sizeof(mgr->payloads[0])/sizeof(mgr->proposed_vcpis[0]) instead - vsyrjala
drivers/gpu/drm/drm_dp_mst_topology.c +6 -1
@@ -3447,6 +3447,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool msint ret =0 ;struct drm_dp_mst_branch *mstb =NULL ; +mutex_lock (&mgr->payload_lock);mutex_lock (&mgr->lock);if (mst_state == mgr->mst_state) goto out_unlock;
@@ -3505,7 +3506,10 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms/* this can fail if the device is gone */ drm_dp_dpcd_writeb (mgr->aux,DP_MSTM_CTRL ,0 ); ret =0 ; -memset (mgr->payloads,0 , mgr->max_payloads *sizeof (struct drm_dp_payload )); +memset (mgr->payloads,0 , + mgr->max_payloads *sizeof (mgr->payloads[0 ])); +memset (mgr->proposed_vcpis,0 , + mgr->max_payloads *sizeof (mgr->proposed_vcpis[0 ])); mgr->payload_mask =0 ;set_bit (0 , &mgr->payload_mask); mgr->vcpi_mask =0 ;
@@ -3514,6 +3518,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms out_unlock:mutex_unlock (&mgr->lock); +mutex_unlock (&mgr->payload_lock);if (mstb)drm_dp_mst_topology_put_mstb (mstb);return ret;
PATCH 1/1 drm/dp_mst: Fix clearing payload state on topology disable
The issues caused by:
commit 64e62bdf04ab ("drm/dp_mst: Remove VCPI while disabling topology mgr")
Prompted me to take a closer look at how we clear the payload state in general when disabling the topology, and it turns out there's actually two subtle issues here.
The first is that we're not grabbing &mgr.payload_lock when clearing the payloads in drm_dp_mst_topology_mgr_set_mst(). Seeing as the canonical lock order is &mgr.payload_lock -> &mgr.lock (because we always want &mgr.lock to be the inner-most lock so topology validation always works), this makes perfect sense. It also means that -technically- there could be racing between someone calling drm_dp_mst_topology_mgr_set_mst() to disable the topology, along with a modeset occurring that's modifying the payload state at the same time.
The second is the more obvious issue that Wayne Lin discovered, that we're not clearing proposed_payloads when disabling the topology.
I actually can't see any obvious places where the racing caused by the first issue would break something, and it could be that some of our higher-level locks already prevent this by happenstance, but better safe then sorry. So, let's make it so that drm_dp_mst_topology_mgr_set_mst() first grabs &mgr.payload_lock followed by &mgr.lock so that we never race when modifying the payload state. Then, we also clear proposed_payloads to fix the original issue of enabling a new topology with a dirty payload state. This doesn't clear any of the drm_dp_vcpi structures, but those are getting destroyed along with the ports anyway.
Changes since v1:
* Use sizeof(mgr->payloads[0])/sizeof(mgr->proposed_vcpis[0]) instead - vsyrjala
---
Hey Greg! This should apply to 5.6, I'll check in just a little bit whether or not I need to backport this to other kernel versions as well
drivers/gpu/drm/drm_dp_mst_topology.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +6 -4
@@ -3507,6 +3507,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool msint i =0 ;struct drm_dp_mst_branch *mstb =NULL ; +mutex_lock (&mgr->payload_lock);mutex_lock (&mgr->lock);if (mst_state == mgr->mst_state) goto out_unlock;
@@ -3565,8 +3566,10 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms/* this can fail if the device is gone */ drm_dp_dpcd_writeb (mgr->aux,DP_MSTM_CTRL ,0 ); ret =0 ; -mutex_lock (&mgr->payload_lock); -memset (mgr->payloads,0 , mgr->max_payloads *sizeof (struct drm_dp_payload )); +memset (mgr->payloads,0 , + mgr->max_payloads *sizeof (mgr->payloads[0 ])); +memset (mgr->proposed_vcpis,0 , + mgr->max_payloads *sizeof (mgr->proposed_vcpis[0 ])); mgr->payload_mask =0 ;set_bit (0 , &mgr->payload_mask);for (i =0 ; i < mgr->max_payloads; i++) {
@@ -3579,13 +3582,12 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms mgr->proposed_vcpis[i] =NULL ; } mgr->vcpi_mask =0 ; -mutex_unlock (&mgr->payload_lock); - mgr->payload_id_table_cleared = false; } out_unlock:mutex_unlock (&mgr->lock); +mutex_unlock (&mgr->payload_lock);if (mstb)drm_dp_mst_topology_put_mstb (mstb);return ret;
Signature · 6 lines
2.25.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel
Sasha Levin
maintainerQuoted 55 lines · On Wed, Apr 15, 2020 at 01:31:37PM +0200, [email protected] wrote:
The patch below does not apply to the 5.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From
8732fe46b20c951493bfc4dba0ad08efdf41de81Mon Sep 17 00:00:00 2001
From: Lyude Paul <[email protected]>
Date: Wed, 22 Jan 2020 14:43:20 -0500
Subject: [PATCH] drm/dp_mst: Fix clearing payload state on topology disable
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bitThe issues caused by:
commit
64e62bdf04ab("drm/dp_mst: Remove VCPI while disabling topology mgr")Prompted me to take a closer look at how we clear the payload state in general when disabling the topology, and it turns out there's actually two subtle issues here.
The first is that we're not grabbing &mgr.payload_lock when clearing the payloads in
drm_dp_mst_topology_mgr_set_mst(). Seeing as the canonical lock order is &mgr.payload_lock -> &mgr.lock (because we always want &mgr.lock to be the inner-most lock so topology validation always works), this makes perfect sense. It also means that -technically- there could be racing between someone callingdrm_dp_mst_topology_mgr_set_mst()to disable the topology, along with a modeset occurring that's modifying the payload state at the same time.The second is the more obvious issue that Wayne Lin discovered, that we're not clearing
proposed_payloadswhen disabling the topology.I actually can't see any obvious places where the racing caused by the first issue would break something, and it could be that some of our higher-level locks already prevent this by happenstance, but better safe then sorry. So, let's make it so that
drm_dp_mst_topology_mgr_set_mst()first grabs &mgr.payload_lock followed by &mgr.lock so that we never race when modifying the payload state. Then, we also clearproposed_payloadsto fix the original issue of enabling a new topology with a dirty payload state. This doesn't clear any of thedrm_dp_vcpistructures, but those are getting destroyed along with the ports anyway.Changes since v1:
* Use sizeof(mgr->payloads[0])/sizeof(mgr->proposed_vcpis[0]) instead - vsyrjala
Quoted 7 lines
Cc Sean Paul <[email protected]>Cc Wayne Lin <[email protected]>Cc Ville Syrjälä <[email protected]>Cc [email protected] # v4.4+Signed-off-by Lyude Paul <[email protected]>Reviewed-by Ville Syrjälä <[email protected]>
We needed a86675968e23 ("Revert "drm/dp_mst: Remove VCPI while disabling topology mgr"") too (this is a revert of a stable tagged commit).
Signature · 2 lines
Thanks, Sasha