drm/dp: look up the mstb passed into work function (v2)
Subsystems (2)
Dave Airlie
maintainerPATCH 1/2 drm/dp: look up the mstb passed into work function (v2)
From: Dave Airlie <[email protected]>
We should validate the passed in mstb under the lock this should stop us getting an invalid mstb here.
(first attempt with cancelling work has lockdep issues).
Bugzilla: https://bugs.archlinux.org/task/45369
v2: update bugzilla, add some notes on why passing mst_primary is okay.
--- drivers/gpu/drm/drm_dp_mst_topology.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/gpu/drm/drm_dp_mst_topology.c +15 -2
@@ -1198,9 +1198,14 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_ }static void drm_dp_check_and_send_link_address (struct drm_dp_mst_topology_mgr *mgr, -struct drm_dp_mst_branch *mstb) +struct drm_dp_mst_branch *mstb_in) {struct drm_dp_mst_port *port; +struct drm_dp_mst_branch *mstb; + + mstb =drm_dp_get_validated_mstb_ref (mgr, mstb_in); +if (!mstb) +return ;if (!mstb->link_address_sent) {drm_dp_send_link_address (mgr, mstb);
@@ -1219,12 +1224,20 @@ static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mif (port->mstb)drm_dp_check_and_send_link_address (mgr, port->mstb); } +drm_dp_put_mst_branch_device (mstb); }static void drm_dp_mst_link_probe_work (struct work_struct *work) { struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work); - +/* +* Note this passes mgr->mst_primary without validation +* it could be a) valid, b) NULL, c) some value between +* since we haven't taken the lock, +* however the validation sequence in check and send +* will take the lock, and if the value isn't valid +* it will fail appropriately. +*/ drm_dp_check_and_send_link_address (mgr, mgr->mst_primary); }
Signature · 6 lines
2.4.1 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Dave Airlie
maintainerPATCH 2/2 drm/dp/mst: take lock around looking up the branch device on hpd irq
From: Dave Airlie <[email protected]>
If we are doing an MST transaction and we've gotten HPD and we lookup the device from the incoming msg, we should take the mgr lock around it, so that mst_primary and mstb->ports are valid.
--- drivers/gpu/drm/drm_dp_mst_topology.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/drm_dp_mst_topology.c +3 -0
@@ -1175,6 +1175,8 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_struct drm_dp_mst_port *port;int i;/* find the port by iterating down */ + +mutex_lock (&mgr->lock); mstb = mgr->mst_primary;for (i =0 ; i < lct -1 ; i++) {
@@ -1194,6 +1196,7 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_ } }kref_get (&mstb->kref); +mutex_unlock (&mgr->lock);return mstb; }
Signature · 6 lines
2.4.1 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/2] drm/dp/mst: take lock around looking up the branch device on hpd irq
Quoted 7 lines · Dave Airlie
From: Dave Airlie <[email protected]>
If we are doing an MST transaction and we've gotten HPD and we lookup the device from the incoming msg, we should take the mgr lock around it, so that
mst_primaryandmstb->portsare valid.Signed-off-by Dave Airlie <[email protected]>
Quoted 32 lines
--- drivers/gpu/drm/drm_dp_mst_topology.c | 3 +++ 1 file changed, 3 insertions(+)drivers/gpu/drm/drm_dp_mst_topology.c +3
-0@@ -1175,6 +1175,8 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_struct drm_dp_mst_port *port;int i;/* find the port by iterating down */ + +mutex_lock (&mgr->lock); mstb = mgr->mst_primary;for (i =0 ; i < lct -1 ; i++) {@@ -1194,6 +1196,7 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_ } }kref_get (&mstb->kref); +mutex_unlock (&mgr->lock);return mstb; }Signature · 6 lines
2.4.1 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 2/2] drm/dp/mst: take lock around looking up the branch device on hpd irq
Quoted 10 lines · Daniel Vetter
Quoted 7 lines · Dave Airlie
From: Dave Airlie <[email protected]>
If we are doing an MST transaction and we've gotten HPD and we lookup the device from the incoming msg, we should take the mgr lock around it, so that
mst_primaryandmstb->portsare valid.Signed-off-by Dave Airlie <[email protected]>Reviewed-by Daniel Vetter <[email protected]>
The error path fails to unlock the mutex, reported in [1]. There's a fix in the bug, I've asked Adam to post it to the list.
BR,
Jani.
[1] https://bugs.freedesktop.org/show_bug.cgi?id=92480
Quoted 42 lines
Quoted 33 lines
--- drivers/gpu/drm/drm_dp_mst_topology.c | 3 +++ 1 file changed, 3 insertions(+)drivers/gpu/drm/drm_dp_mst_topology.c +3
-0@@ -1175,6 +1175,8 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_struct drm_dp_mst_port *port;int i;/* find the port by iterating down */ + +mutex_lock (&mgr->lock); mstb = mgr->mst_primary;for (i =0 ; i < lct -1 ; i++) {@@ -1194,6 +1196,7 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_ } }kref_get (&mstb->kref); +mutex_unlock (&mgr->lock);return mstb; }Signature · 6 lines
2.4.1 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-develSignature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 5 lines
Jani Nikula, Intel Open Source Technology Center _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 5 lines · Dave Airlie
From: Dave Airlie <[email protected]>
We should validate the passed in mstb under the lock this should stop us getting an invalid mstb here.
Quoted 7 lines
(first attempt with cancelling work has lockdep issues).
Bugzilla: https://bugs.archlinux.org/task/45369v2: update bugzilla, add some notes on why passing
mst_primaryis okay.Signed-off-by Dave Airlie <[email protected]>
On 2nd look I realized that pulling out mgr->lock and using the _locked variant won't work cleanly since the _put might also take the mgr->lock. I guess we could fix that too by also pulling the ref grab/drop for its argument out of check_and_send like this:
drivers/gpu/drm/drm_dp_mst_topology.c +18 -3
@@ -1189,6 +1189,7 @@ static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *m struct drm_dp_mst_branch *mstb) {struct drm_dp_mst_port *port; +struct drm_dp_mst_branch *mstb_child;if (!mstb->link_address_sent) {drm_dp_send_link_address (mgr, mstb);
@@ -1204,17 +1205,31 @@ static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mif (!port->available_pbn)drm_dp_send_enum_path_resources (mgr, mstb, port); -if (port->mstb) -drm_dp_check_and_send_link_address (mgr, port->mstb); +if (port->mstb) { + mstb_child =drm_dp_get_validated_mstb_ref (mgr, + port->mstb); +if (mstb_child) { +drm_dp_check_and_send_link_address (mgr, + mstb_child); +drm_dp_put_mst_branch_device (mstb_child); + } + } } }static void drm_dp_mst_link_probe_work (struct work_struct *work) { struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work); +struct drm_dp_mst_branch *mstb; -drm_dp_check_and_send_link_address (mgr, mgr->mst_primary); +mutex_lock (&mgr->lock); +kref_get (&mgr->mst_primary->kref); + mstb = mgr->mst_primary; +mutex_unlock (&mgr->lock); +drm_dp_check_and_send_link_address (mgr, mstb); + +drm_dp_put_mst_branch_device (mstb); } static bool drm_dp_validate_guid(struct drm_dp_mst_topology_mgr *mgr,
Upside is that we don't need a comment, and imo non-tricky code is better code. Or am I still missing something?
-Daniel
Quoted 53 lines
--- drivers/gpu/drm/drm_dp_mst_topology.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)drivers/gpu/drm/drm_dp_mst_topology.c +15
-2@@ -1198,9 +1198,14 @@ static struct drm_dp_mst_branch *drm_dp_get_mst_branch_device(struct drm_dp_mst_ }static void drm_dp_check_and_send_link_address (struct drm_dp_mst_topology_mgr *mgr, -struct drm_dp_mst_branch *mstb) +struct drm_dp_mst_branch *mstb_in) {struct drm_dp_mst_port *port; +struct drm_dp_mst_branch *mstb; + + mstb =drm_dp_get_validated_mstb_ref (mgr, mstb_in); +if (!mstb) +return ;if (!mstb->link_address_sent) {drm_dp_send_link_address (mgr, mstb);@@ -1219,12 +1224,20 @@ static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mif (port->mstb)drm_dp_check_and_send_link_address (mgr, port->mstb); } +drm_dp_put_mst_branch_device (mstb); }static void drm_dp_mst_link_probe_work (struct work_struct *work) { struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, work); - +/* +* Note this passes mgr->mst_primary without validation +* it could be a) valid, b) NULL, c) some value between +* since we haven't taken the lock, +* however the validation sequence in check and send +* will take the lock, and if the value isn't valid +* it will fail appropriately. +*/ drm_dp_check_and_send_link_address (mgr, mgr->mst_primary); }Signature · 6 lines
2.4.1 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Signature · 7 lines
Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel