CHROMIUM: drm/mst: More hacks on mst connector destroy

This patch is fixing up the fix introduced in crosreview.com/2222915

Last time around we saw the double port frees and used the
destroy_connector_lock to serialize detect and destroy. When we did
that, the port->kref was assumed to be 1 in destroy_connector_work.

As it turns out, destroy_connector_work is queued when the branch device
is destroyed and the port kref should actually be 0. The previous code
had a rogue kref_init which seemed to do nothing, but it actually bumps the
refcount back up in order to call reset_vcpi_slots and
update_payload_part1 on the port during destroy.

Unfortunately update_payload_part1 tries to grab references on other ports
which may also be in the destroy_connector_list and have refcount == 0.
If that happens, the port will be re-queued for destroy and we'll end up
oopsing the kernel by freeing this port twice.

--
Example:
Suppose an mst branch with 2 output ports, port1 and port2.

When the mst branch is destroyed, the initial reference port1 and port2
are created with (during branch creation) are given back and these
ports are added to destroy_connector_list. In destroy_connector_work, we
pick port1 off the list and call update_payload_part1. This will grab a
reference to port2 (which is sitting at 0) so port2's refcount goes from
0->1. When port1's call to update_payload_part1 is done with port2, it'll
decrease the refcount (1->0) which will queue it for destruction. So now
port2 appears in the destroy list twice and will be freed twice.
--

So this patch adds a loop through the connector_list and re-initializes
all port krefs before trying to destroy anything. This ensures that if
update_payload_part1 for port1 needs a ref on port2, it can grab it.

Additionally, add another WARN to ensure the refcounts are being handled
appropriately.

BUG=b:159220596,b:144866969
TEST=Tested on atlas with 2 MST displays connected. Unplug the hub and
observe WARN + lockup

Signed-off-by: Sean Paul <seanpaul@chromium.org>
Change-Id: Ifc9702108fb629166f0727db7bfd0c762bc90aa4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2257744
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
(cherry picked from commit c4c99f3774d44347e7f6064bbaf0ba7517d4178f)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2276395
(cherry picked from commit e30e3b976ebc89c5a62a1ab099ffb2ad42ff2c0e)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2296159
1 file changed