Re: [PATCH 1/6] drm/dp_mst: Introduce drm_dp_mst_connector_atomic_check()

2018-09-20 Thread Harry Wentland
On 2018-09-18 07:06 PM, Lyude Paul wrote:
> Currently the way that we prevent userspace from performing new modesets
> on MST connectors that have just been destroyed is rather broken.
> There's nothing in the actual DRM DP MST topology helpers that checks
> whether or not a connector still exists, instead each DRM driver does
> this on it's own, usually by returning NULL from the best_encoder
> callback which in turn, causes the atomic commit to fail.
> 
> However, this is wrong in a rather subtle way. If ->best_encoder()
> returns NULL, this makes ALL modesets involving the connector fail. This
> includes modesets from userspace that would shut off the CRTCs being
> used by the connector. Since this results in blocking any changes to a
> connector's DPMS prop, it has the sideaffect of preventing legacy
> modesetting users from ever disabling a CRTC that was previously enabled
> for use in an MST topology. An example of this, where X tries to
> change the DPMS property of an MST connector that was just detached from
> the system:
> 
> [ 2908.320131] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] 
> [CONNECTOR:82:DP-6]
> [ 2908.320148] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] 
> [CONNECTOR:82:DP-6] status updated from connected to disconnected
> [ 2908.320166] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] 
> [CONNECTOR:82:DP-6] disconnected
> [ 2908.320193] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 111 (1)
> [ 2908.320230] [drm:drm_sysfs_hotplug_event [drm]] generating hotplug event
> ...
> [ 2908.638539] [drm:drm_ioctl [drm]] pid=12928, dev=0xe201, auth=1, 
> DRM_IOCTL_MODE_SETPROPERTY
> [ 2908.638546] [drm:drm_atomic_state_init [drm]] Allocated atomic state 
> 7155ba49
> [ 2908.638553] [drm:drm_mode_object_get [drm]] OBJ ID: 114 (1)
> [ 2908.638560] [drm:drm_mode_object_get [drm]] OBJ ID: 108 (1)
> [ 2908.638568] [drm:drm_atomic_get_crtc_state [drm]] Added [CRTC:41:head-0] 
> 97a6396e state to 7155ba49
> [ 2908.638575] [drm:drm_atomic_add_affected_connectors [drm]] Adding all 
> current connectors for [CRTC:41:head-0] to 7155ba49
> [ 2908.638582] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (3)
> [ 2908.638589] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (4)
> [ 2908.638596] [drm:drm_atomic_get_connector_state [drm]] Added 
> [CONNECTOR:82:DP-6] 87427144 state to 7155ba49
> [ 2908.638603] [drm:drm_atomic_check_only [drm]] checking 7155ba49
> [ 2908.638609] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] 
> [CRTC:41:head-0] active changed
> [ 2908.638613] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] 
> Updating routing for [CONNECTOR:82:DP-6]
> [ 2908.638616] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] No 
> suitable encoder found for [CONNECTOR:82:DP-6]
> [ 2908.638623] [drm:drm_atomic_check_only [drm]] atomic driver check for 
> 7155ba49 failed: -22
> [ 2908.638630] [drm:drm_atomic_state_default_clear [drm]] Clearing atomic 
> state 7155ba49
> [ 2908.638637] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (4)
> [ 2908.638643] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (3)
> [ 2908.638650] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 114 (2)
> [ 2908.638656] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 108 (2)
> [ 2908.638663] [drm:__drm_atomic_state_free [drm]] Freeing atomic state 
> 7155ba49
> [ 2908.638669] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (2)
> [ 2908.638676] [drm:drm_ioctl [drm]] pid=12928, ret = -22
> 
> While this doesn't usually result in any errors that would be obvious to
> the user, it does result in us leaving display resources on. This in
> turn leads to unwanted sideaffects like inactive GPUs being left on
> (usually from the resulting leaked runtime PM ref).
> 
> So, provide an easier way of doing this that doesn't require breaking
> ->best_encoder(): add a common drm_dp_mst_connector_atomic_check()
> function that DRM drivers can call in order to have CRTC enabling
> commits fail automatically if the MST port driving the connector no
> longer exists. We'll also be able to expand upon this later as well once
> we add MST fallback retraining support.
> 
> Signed-off-by: Lyude Paul 
> Cc: sta...@vger.kernel.org

This does seem like a saner way to handle the case when the MST connector is 
gone. As this doesn't currently seem to affect amdgpu directly and I therefore 
might miss something I'll leave the RB to someone else, but you have my
Acked-by: Harry Wentland 

Harry

> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 76 +++
>  include/drm/drm_dp_mst_helper.h   |  3 ++
>  2 files changed, 79 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 7780567aa669..0162d4bf2549 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3129,6 +3129,82 @@ static 

Re: [PATCH 1/6] drm/dp_mst: Introduce drm_dp_mst_connector_atomic_check()

2018-09-20 Thread Dan Carpenter
Hi Lyude,

Thank you for the patch! Perhaps something to improve:

url:
https://github.com/0day-ci/linux/commits/Lyude-Paul/Fix-legacy-DPMS-changes-with-MST/20180919-203434
base:   git://anongit.freedesktop.org/drm-intel for-linux-next

smatch warnings:
drivers/gpu/drm/drm_dp_mst_topology.c:3144 drm_dp_mst_connector_still_exists() 
error: we previously assumed 'port' could be null (see line 3146)

# 
https://github.com/0day-ci/linux/commit/f8df31d5221b9a6da6698d4a37e622253bb17cdc
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout f8df31d5221b9a6da6698d4a37e622253bb17cdc
vim +/port +3144 drivers/gpu/drm/drm_dp_mst_topology.c

3f3353b7 Pandiyan, Dhinakaran 2017-04-20  3131  
f8df31d5 Lyude Paul   2018-09-18  3132  static bool
f8df31d5 Lyude Paul   2018-09-18  3133  
drm_dp_mst_connector_still_exists(struct drm_connector *connector,
f8df31d5 Lyude Paul   2018-09-18  3134  
  struct drm_dp_mst_topology_mgr *mgr,
f8df31d5 Lyude Paul   2018-09-18  3135  
  struct drm_dp_mst_branch *mstb)
f8df31d5 Lyude Paul   2018-09-18  3136  {
f8df31d5 Lyude Paul   2018-09-18  3137  struct drm_dp_mst_port 
*port;
f8df31d5 Lyude Paul   2018-09-18  3138  bool exists = false;
f8df31d5 Lyude Paul   2018-09-18  3139  
f8df31d5 Lyude Paul   2018-09-18  3140  mstb = 
drm_dp_get_validated_mstb_ref(mgr, mstb);
f8df31d5 Lyude Paul   2018-09-18  3141  if (!mstb)
f8df31d5 Lyude Paul   2018-09-18  3142  return false;
f8df31d5 Lyude Paul   2018-09-18  3143  
f8df31d5 Lyude Paul   2018-09-18 @3144  
list_for_each_entry(port, >ports, next) {

We need to use a different loop iterator, or possibly
list_for_each_entry_safe() because it looks like we're freeing
something.  Maybe it's cleanest to do both.

f8df31d5 Lyude Paul   2018-09-18  3145  port = 
drm_dp_get_validated_port_ref(mgr, port);
f8df31d5 Lyude Paul   2018-09-18 @3146  if (!port)
f8df31d5 Lyude Paul   2018-09-18  3147  
continue;
f8df31d5 Lyude Paul   2018-09-18  3148  
f8df31d5 Lyude Paul   2018-09-18  3149  exists = 
(port->connector == connector ||
f8df31d5 Lyude Paul   2018-09-18  3150
(port->mstb &&
f8df31d5 Lyude Paul   2018-09-18  3151 
drm_dp_mst_connector_still_exists(connector, mgr,
f8df31d5 Lyude Paul   2018-09-18  3152  
 port->mstb)));
f8df31d5 Lyude Paul   2018-09-18  3153  
f8df31d5 Lyude Paul   2018-09-18  3154  
drm_dp_put_port(port);
f8df31d5 Lyude Paul   2018-09-18  3155  if (exists)
f8df31d5 Lyude Paul   2018-09-18  3156  break;
f8df31d5 Lyude Paul   2018-09-18  3157  }
f8df31d5 Lyude Paul   2018-09-18  3158  
f8df31d5 Lyude Paul   2018-09-18  3159  
drm_dp_put_mst_branch_device(mstb);
f8df31d5 Lyude Paul   2018-09-18  3160  return exists;
f8df31d5 Lyude Paul   2018-09-18  3161  }
f8df31d5 Lyude Paul   2018-09-18  3162  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/6] drm/dp_mst: Introduce drm_dp_mst_connector_atomic_check() (fwd)

2018-09-19 Thread Julia Lawall
Hello,

I don't think you can update the loop index variable in
list_for_each_entry, because the mcro uses th index variable to get to the
next element.  Perhaps list_for_each_entry_safe would be more suitable?

julia

-- Forwarded message --
Date: Thu, 20 Sep 2018 04:30:13 +0800
From: kbuild test robot 
To: kbu...@01.org
Cc: Julia Lawall 
Subject: Re: [PATCH 1/6] drm/dp_mst: Introduce
drm_dp_mst_connector_atomic_check()

CC: kbuild-...@01.org
In-Reply-To: <20180918230637.20700-2-ly...@redhat.com>
References: <20180918230637.20700-2-ly...@redhat.com>
TO: Lyude Paul 
CC: dri-de...@lists.freedesktop.org, nouv...@lists.freedesktop.org, 
intel-...@lists.freedesktop.org, amd-gfx@lists.freedesktop.org
CC: David Airlie , linux-ker...@vger.kernel.org, 
sta...@vger.kernel.org, Sean Paul 

Hi Lyude,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-intel/for-linux-next]
[also build test WARNING on v4.19-rc4 next-20180919]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Lyude-Paul/Fix-legacy-DPMS-changes-with-MST/20180919-203434
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
:: branch date: 8 hours ago
:: commit date: 8 hours ago

>> drivers/gpu/drm/drm_dp_mst_topology.c:3144:1-20: iterator with update on 
>> line 3145

# 
https://github.com/0day-ci/linux/commit/f8df31d5221b9a6da6698d4a37e622253bb17cdc
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout f8df31d5221b9a6da6698d4a37e622253bb17cdc
vim +3144 drivers/gpu/drm/drm_dp_mst_topology.c

3f3353b7 Pandiyan, Dhinakaran 2017-04-20  3131
f8df31d5 Lyude Paul   2018-09-18  3132  static bool
f8df31d5 Lyude Paul   2018-09-18  3133  
drm_dp_mst_connector_still_exists(struct drm_connector *connector,
f8df31d5 Lyude Paul   2018-09-18  3134  
  struct drm_dp_mst_topology_mgr *mgr,
f8df31d5 Lyude Paul   2018-09-18  3135  
  struct drm_dp_mst_branch *mstb)
f8df31d5 Lyude Paul   2018-09-18  3136  {
f8df31d5 Lyude Paul   2018-09-18  3137  struct drm_dp_mst_port 
*port;
f8df31d5 Lyude Paul   2018-09-18  3138  bool exists = false;
f8df31d5 Lyude Paul   2018-09-18  3139
f8df31d5 Lyude Paul   2018-09-18  3140  mstb = 
drm_dp_get_validated_mstb_ref(mgr, mstb);
f8df31d5 Lyude Paul   2018-09-18  3141  if (!mstb)
f8df31d5 Lyude Paul   2018-09-18  3142  return false;
f8df31d5 Lyude Paul   2018-09-18  3143
f8df31d5 Lyude Paul   2018-09-18 @3144  
list_for_each_entry(port, >ports, next) {
f8df31d5 Lyude Paul   2018-09-18 @3145  port = 
drm_dp_get_validated_port_ref(mgr, port);
f8df31d5 Lyude Paul   2018-09-18  3146  if (!port)
f8df31d5 Lyude Paul   2018-09-18  3147  
continue;
f8df31d5 Lyude Paul   2018-09-18  3148
f8df31d5 Lyude Paul   2018-09-18  3149  exists = 
(port->connector == connector ||
f8df31d5 Lyude Paul   2018-09-18  3150
(port->mstb &&
f8df31d5 Lyude Paul   2018-09-18  3151 
drm_dp_mst_connector_still_exists(connector, mgr,
f8df31d5 Lyude Paul   2018-09-18  3152  
 port->mstb)));
f8df31d5 Lyude Paul   2018-09-18  3153
f8df31d5 Lyude Paul   2018-09-18  3154  
drm_dp_put_port(port);
f8df31d5 Lyude Paul   2018-09-18  3155  if (exists)
f8df31d5 Lyude Paul   2018-09-18  3156  break;
f8df31d5 Lyude Paul   2018-09-18  3157  }
f8df31d5 Lyude Paul   2018-09-18  3158
f8df31d5 Lyude Paul   2018-09-18  3159  
drm_dp_put_mst_branch_device(mstb);
f8df31d5 Lyude Paul   2018-09-18  3160  return exists;
f8df31d5 Lyude Paul   2018-09-18  3161  }
f8df31d5 Lyude Paul   2018-09-18  3162

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


Re: [PATCH 1/6] drm/dp_mst: Introduce drm_dp_mst_connector_atomic_check() (fwd)

2018-09-19 Thread Lyude Paul
oh, good catch! will fix and respin in just a little bit

On Wed, 2018-09-19 at 22:38 +0200, Julia Lawall wrote:
> Hello,
> 
> I don't think you can update the loop index variable in
> list_for_each_entry, because the mcro uses th index variable to get to the
> next element.  Perhaps list_for_each_entry_safe would be more suitable?
> 
> julia
> 
> -- Forwarded message --
> Date: Thu, 20 Sep 2018 04:30:13 +0800
> From: kbuild test robot 
> To: kbu...@01.org
> Cc: Julia Lawall 
> Subject: Re: [PATCH 1/6] drm/dp_mst: Introduce
> drm_dp_mst_connector_atomic_check()
> 
> CC: kbuild-...@01.org
> In-Reply-To: <20180918230637.20700-2-ly...@redhat.com>
> References: <20180918230637.20700-2-ly...@redhat.com>
> TO: Lyude Paul 
> CC: dri-de...@lists.freedesktop.org, nouv...@lists.freedesktop.org, 
> intel-...@lists.freedesktop.org, amd-gfx@lists.freedesktop.org
> CC: David Airlie , linux-ker...@vger.kernel.org, 
> sta...@vger.kernel.org, Sean Paul 
> 
> Hi Lyude,
> 
> Thank you for the patch! Perhaps something to improve:
> 
> [auto build test WARNING on drm-intel/for-linux-next]
> [also build test WARNING on v4.19-rc4 next-20180919]
> [if your patch is applied to the wrong git tree, please drop us a note to help
> improve the system]
> 
> url:
> https://github.com/0day-ci/linux/commits/Lyude-Paul/Fix-legacy-DPMS-changes-with-MST/20180919-203434
> base:   git://anongit.freedesktop.org/drm-intel for-linux-next
> :: branch date: 8 hours ago
> :: commit date: 8 hours ago
> 
> > > drivers/gpu/drm/drm_dp_mst_topology.c:3144:1-20: iterator with update on
> > > line 3145
> 
> # 
> https://github.com/0day-ci/linux/commit/f8df31d5221b9a6da6698d4a37e622253bb17cdc
> git remote add linux-review https://github.com/0day-ci/linux
> git remote update linux-review
> git checkout f8df31d5221b9a6da6698d4a37e622253bb17cdc
> vim +3144 drivers/gpu/drm/drm_dp_mst_topology.c
> 
> 3f3353b7 Pandiyan, Dhinakaran 2017-04-20  3131
> f8df31d5 Lyude Paul   2018-09-18  3132  static bool
> f8df31d5 Lyude Paul   2018-09-
> 18  3133  drm_dp_mst_connector_still_exists(struct drm_connector *connector,
> f8df31d5 Lyude Paul   2018-09-18  3134
>   struct drm_dp_mst_topology_mgr *mgr,
> f8df31d5 Lyude Paul   2018-09-18  3135
>   struct drm_dp_mst_branch *mstb)
> f8df31d5 Lyude Paul   2018-09-18  3136  {
> f8df31d5 Lyude Paul   2018-09-18  3137struct drm_dp_mst_port
> *port;
> f8df31d5 Lyude Paul   2018-09-18  3138bool exists = false;
> f8df31d5 Lyude Paul   2018-09-18  3139
> f8df31d5 Lyude Paul   2018-09-18  3140mstb =
> drm_dp_get_validated_mstb_ref(mgr, mstb);
> f8df31d5 Lyude Paul   2018-09-18  3141if (!mstb)
> f8df31d5 Lyude Paul   2018-09-18  3142return false;
> f8df31d5 Lyude Paul   2018-09-18  3143
> f8df31d5 Lyude Paul   2018-09-18 @3144list_for_each_entry(port
> , >ports, next) {
> f8df31d5 Lyude Paul   2018-09-18 @3145port =
> drm_dp_get_validated_port_ref(mgr, port);
> f8df31d5 Lyude Paul   2018-09-18  3146if (!port)
> f8df31d5 Lyude Paul   2018-09-18  3147continue
> ;
> f8df31d5 Lyude Paul   2018-09-18  3148
> f8df31d5 Lyude Paul   2018-09-18  3149exists = (port-
> >connector == connector ||
> f8df31d5 Lyude Paul   2018-09-18  3150  (port-
> >mstb &&
> f8df31d5 Lyude Paul   2018-09-18  3151   drm_d
> p_mst_connector_still_exists(connector, mgr,
> f8df31d5 Lyude Paul   2018-09-18  3152
> 
>port->mstb)));
> f8df31d5 Lyude Paul   2018-09-18  3153
> f8df31d5 Lyude Paul   2018-09-18  3154drm_dp_put_port(
> port);
> f8df31d5 Lyude Paul   2018-09-18  3155if (exists)
> f8df31d5 Lyude Paul   2018-09-18  3156break;
> f8df31d5 Lyude Paul   2018-09-18  3157}
> f8df31d5 Lyude Paul   2018-09-18  3158
> f8df31d5 Lyude Paul   2018-09-18  3159drm_dp_put_mst_branch_de
> vice(mstb);
> f8df31d5 Lyude Paul   2018-09-18  3160return exists;
> f8df31d5 Lyude Paul   2018-09-18  3161  }
> f8df31d5 Lyude Paul   2018-09-18  3162
> 
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[PATCH 1/6] drm/dp_mst: Introduce drm_dp_mst_connector_atomic_check()

2018-09-18 Thread Lyude Paul
Currently the way that we prevent userspace from performing new modesets
on MST connectors that have just been destroyed is rather broken.
There's nothing in the actual DRM DP MST topology helpers that checks
whether or not a connector still exists, instead each DRM driver does
this on it's own, usually by returning NULL from the best_encoder
callback which in turn, causes the atomic commit to fail.

However, this is wrong in a rather subtle way. If ->best_encoder()
returns NULL, this makes ALL modesets involving the connector fail. This
includes modesets from userspace that would shut off the CRTCs being
used by the connector. Since this results in blocking any changes to a
connector's DPMS prop, it has the sideaffect of preventing legacy
modesetting users from ever disabling a CRTC that was previously enabled
for use in an MST topology. An example of this, where X tries to
change the DPMS property of an MST connector that was just detached from
the system:

[ 2908.320131] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] 
[CONNECTOR:82:DP-6]
[ 2908.320148] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] 
[CONNECTOR:82:DP-6] status updated from connected to disconnected
[ 2908.320166] [drm:drm_helper_probe_single_connector_modes [drm_kms_helper]] 
[CONNECTOR:82:DP-6] disconnected
[ 2908.320193] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 111 (1)
[ 2908.320230] [drm:drm_sysfs_hotplug_event [drm]] generating hotplug event
...
[ 2908.638539] [drm:drm_ioctl [drm]] pid=12928, dev=0xe201, auth=1, 
DRM_IOCTL_MODE_SETPROPERTY
[ 2908.638546] [drm:drm_atomic_state_init [drm]] Allocated atomic state 
7155ba49
[ 2908.638553] [drm:drm_mode_object_get [drm]] OBJ ID: 114 (1)
[ 2908.638560] [drm:drm_mode_object_get [drm]] OBJ ID: 108 (1)
[ 2908.638568] [drm:drm_atomic_get_crtc_state [drm]] Added [CRTC:41:head-0] 
97a6396e state to 7155ba49
[ 2908.638575] [drm:drm_atomic_add_affected_connectors [drm]] Adding all 
current connectors for [CRTC:41:head-0] to 7155ba49
[ 2908.638582] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (3)
[ 2908.638589] [drm:drm_mode_object_get [drm]] OBJ ID: 82 (4)
[ 2908.638596] [drm:drm_atomic_get_connector_state [drm]] Added 
[CONNECTOR:82:DP-6] 87427144 state to 7155ba49
[ 2908.638603] [drm:drm_atomic_check_only [drm]] checking 7155ba49
[ 2908.638609] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] 
[CRTC:41:head-0] active changed
[ 2908.638613] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] Updating 
routing for [CONNECTOR:82:DP-6]
[ 2908.638616] [drm:drm_atomic_helper_check_modeset [drm_kms_helper]] No 
suitable encoder found for [CONNECTOR:82:DP-6]
[ 2908.638623] [drm:drm_atomic_check_only [drm]] atomic driver check for 
7155ba49 failed: -22
[ 2908.638630] [drm:drm_atomic_state_default_clear [drm]] Clearing atomic state 
7155ba49
[ 2908.638637] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (4)
[ 2908.638643] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (3)
[ 2908.638650] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 114 (2)
[ 2908.638656] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 108 (2)
[ 2908.638663] [drm:__drm_atomic_state_free [drm]] Freeing atomic state 
7155ba49
[ 2908.638669] [drm:drm_mode_object_put.part.2 [drm]] OBJ ID: 82 (2)
[ 2908.638676] [drm:drm_ioctl [drm]] pid=12928, ret = -22

While this doesn't usually result in any errors that would be obvious to
the user, it does result in us leaving display resources on. This in
turn leads to unwanted sideaffects like inactive GPUs being left on
(usually from the resulting leaked runtime PM ref).

So, provide an easier way of doing this that doesn't require breaking
->best_encoder(): add a common drm_dp_mst_connector_atomic_check()
function that DRM drivers can call in order to have CRTC enabling
commits fail automatically if the MST port driving the connector no
longer exists. We'll also be able to expand upon this later as well once
we add MST fallback retraining support.

Signed-off-by: Lyude Paul 
Cc: sta...@vger.kernel.org
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 76 +++
 include/drm/drm_dp_mst_helper.h   |  3 ++
 2 files changed, 79 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 7780567aa669..0162d4bf2549 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3129,6 +3129,82 @@ static const struct drm_private_state_funcs 
mst_state_funcs = {
.atomic_destroy_state = drm_dp_mst_destroy_state,
 };
 
+static bool
+drm_dp_mst_connector_still_exists(struct drm_connector *connector,
+ struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_branch *mstb)
+{
+   struct drm_dp_mst_port *port;
+   bool exists = false;
+
+   mstb = drm_dp_get_validated_mstb_ref(mgr, mstb);
+   if