drm/dp: look up the mstb passed into work function
Subsystems (2)
Dave Airlie
maintainerPATCH 1/1 drm/dp: look up the mstb passed into work function
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.freedesktop.org/show_bug.cgi?id=89366
--- drivers/gpu/drm/drm_dp_mst_topology.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_dp_mst_topology.c +7 -1
@@ -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,6 +1224,7 @@ 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)
Signature · 6 lines
2.4.1 _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 6 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.
(first attempt with cancelling work has lockdep issues).
Yeah cancel_work_sync is nasty that way ;-)
Btw random bikeshed, but mgr->work would look nice as mgr->probe_work.
Quoted 1 line
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89366
Bugzilla: https://bugs.archlinux.org/task/45369
seems the more accurate one, the fdo one is a mess.
Quoted 27 lines
Signed-off-by Dave Airlie <[email protected]>--- drivers/gpu/drm/drm_dp_mst_topology.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)drivers/gpu/drm/drm_dp_mst_topology.c +6
-1@@ -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);
drivers/gpu/drm/drm_dp_mst_topology.c static void drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *m · line 1228
Quoted 5 lines
drivers/gpu/drm/drm_dp_mst_topology.c +1
-0@@ -1219,6 +1224,7 @@ 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); }
I am a bit concerned about the lifetime rules of the mgr->mst_primary pointer. port->mstb is controlled by the lifetime of the port and that by the parent mst branch, so I think we're covered dereferencing that one.
But mgr->mst_primary seems to be protected only by mgr->lock, and you're not holding that in the probe work. I did review drm_dp_mst_topology_mgr_set_mst and that does seem to clean up ->mst_primary correctly but might be helped with a comment. But we do need the locking I think.
Assuming the added locking doesn't piss off lockdep this is
-Daniel
---
drivers/gpu/drm/drm_dp_mst_topology.c +4 -0
@@ -1213,7 +1213,9 @@ 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); +mutex_lock (&mgr->lock);drm_dp_check_and_send_link_address (mgr, mgr->mst_primary); +mutex_unlock (&mgr->lock); }
@@ -1921,6 +1923,8 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms }else {/* disable MST on the device */ mstb = mgr->mst_primary; +/* inherit reference from ->mst_primary, will be cleaned up +* at the end. */ mgr->mst_primary =NULL ;/* this can fail if the device is gone */ drm_dp_dpcd_writeb (mgr->aux,DP_MSTM_CTRL ,0 );
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
Dave Airlie
maintainerQuoted 8 lines · Daniel Vetter
Quoted 6 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.
(first attempt with cancelling work has lockdep issues).
Quoted 8 lines
Yeah
cancel_work_syncis nasty that way ;-)Btw random bikeshed, but
mgr->workwould look nice asmgr->probe_work.Quoted 1 line
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89366
Bugzilla: https://bugs.archlinux.org/task/45369
seems the more accurate one, the fdo one is a mess.
yes probably.
Quoted 9 lines
I am a bit concerned about the lifetime rules of the
mgr->mst_primarypointer.port->mstbis controlled by the lifetime of the port and that by the parent mst branch, so I think we're covered dereferencing that one.But
mgr->mst_primaryseems to be protected only bymgr->lock, and you're not holding that in the probe work. I did reviewdrm_dp_mst_topology_mgr_set_mstand that does seem to clean up ->mst_primary correctly but might be helped with a comment. But we do need the locking I think.
That won't work as we take the lock to do the lookups later,
It doesn't actually matter if mgr->mst_primary gets messed up here I don't think,
as long as we validate it. So the value is going to be either a) correct, b) NULL,
c) garbage between a and b assuming its not atomic, the validate function locks the mgr, and checks primary, at this point primary will either be a or b as we hold the lock, and if primary from outside the function is a, b or c won't matter as the validation will either pass or fail depending on the state under the
lock.
Though in reviewing that I did find another bug with primary which I'll send another fix for.
Dave.
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 32 lines · Dave Airlie
Quoted 8 lines · Daniel Vetter
Quoted 6 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.
(first attempt with cancelling work has lockdep issues).
Quoted 8 lines
Yeah
cancel_work_syncis nasty that way ;-)Btw random bikeshed, but
mgr->workwould look nice asmgr->probe_work.Quoted 1 line
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=89366
Bugzilla: https://bugs.archlinux.org/task/45369
seems the more accurate one, the fdo one is a mess.
yes probably.
Quoted 9 lines
I am a bit concerned about the lifetime rules of the
mgr->mst_primarypointer.port->mstbis controlled by the lifetime of the port and that by the parent mst branch, so I think we're covered dereferencing that one.But
mgr->mst_primaryseems to be protected only bymgr->lock, and you're not holding that in the probe work. I did reviewdrm_dp_mst_topology_mgr_set_mstand that does seem to clean up ->mst_primary correctly but might be helped with a comment. But we do need the locking I think.That won't work as we take the lock to do the lookups later,
Quoted 10 lines
It doesn't actually matter if
mgr->mst_primarygets messed up here I don't think,
as long as we validate it. So the value is going to be either a) correct, b) NULL,
c) garbage between a and b assuming its not atomic, the validate function locks the mgr, and checks primary, at this point primary will either be a or b as we hold the lock, and if primary from outside the function is a, b or c won't matter as the validation will either pass or fail depending on the state under the
lock.
Hm, I was afraid of some derefencing of the passed-in mstb pointer, but indeed we seem to be covered. Still I think pulling the mgr->lock out and instead using drm_dp_mst_get_validated_mstb_ref_locked in drm_dp_check_and_send_link_address would result in less head-scratching next time we read this code ;-)
-Daniel
Quoted 5 lines
Though in reviewing that I did find another bug with primary which I'll send another fix for.
Dave.
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
Dave Airlie
maintainerQuoted 11 lines
Quoted 10 lines
It doesn't actually matter if
mgr->mst_primarygets messed up here I don't think,
as long as we validate it. So the value is going to be either a) correct, b) NULL,
c) garbage between a and b assuming its not atomic, the validate function locks the mgr, and checks primary, at this point primary will either be a or b as we hold the lock, and if primary from outside the function is a, b or c won't matter as the validation will either pass or fail depending on the state under the
lock.
Quoted 5 lines
Hm, I was afraid of some derefencing of the passed-in mstb pointer, but indeed we seem to be covered. Still I think pulling the
mgr->lockout and instead usingdrm_dp_mst_get_validated_mstb_ref_lockedindrm_dp_check_and_send_link_addresswould result in less head-scratching next time we read this code ;-)
That's why the follow up patch adds a comment. Also that starts down the road of locks protecting code not data, the lock is only needed for the lookup not the whole function. The problem being the function iterates, so then we end up holding the lock for a lot longer than is required IMO.
Dave.
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel