diff options
author | Lyude Paul <lyude@redhat.com> | 2022-08-17 22:38:37 +0300 |
---|---|---|
committer | Lyude Paul <lyude@redhat.com> | 2022-08-23 23:53:37 +0300 |
commit | a5c2c0d164e96d24f73faffcd3b7bbb607e701a9 (patch) | |
tree | e534e930f8acf5942de00c54e3043cae6a2a34b6 /drivers/gpu/drm/i915 | |
parent | 0b4e477e08a14ef852d5a633cee10e4187730005 (diff) | |
download | linux-a5c2c0d164e96d24f73faffcd3b7bbb607e701a9.tar.xz |
drm/display/dp_mst: Add nonblocking helpers for DP MST
As Daniel Vetter pointed out, if we only use the atomic modesetting locks
with MST it's technically possible for a driver with non-blocking modesets
to race when it comes to MST displays - as we make the mistake of not doing
our own CRTC commit tracking in the topology_state object.
This could potentially cause problems if something like this happens:
* User starts non-blocking commit to disable CRTC-1 on MST topology 1
* User starts non-blocking commit to enable CRTC-2 on MST topology 1
There's no guarantee here that the commit for disabling CRTC-2 will only
occur after CRTC-1 has finished, since neither commit shares a CRTC - only
the private modesetting object for MST. Keep in mind this likely isn't a
problem for blocking modesets, only non-blocking.
So, begin fixing this by keeping track of which CRTCs on a topology have
changed by keeping track of which CRTCs we release or allocate timeslots
on. As well, add some helpers for:
* Setting up the drm_crtc_commit structs in the ->commit_setup hook
* Waiting for any CRTC dependencies from the previous topology state
v2:
* Use drm_dp_mst_atomic_setup_commit() directly - Jani
Signed-off-by: Lyude Paul <lyude@redhat.com>
Cc: Wayne Lin <Wayne.Lin@amd.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Fangzhi Zuo <Jerry.Zuo@amd.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Sean Paul <sean@poorly.run>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220817193847.557945-9-lyude@redhat.com
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bf170bd83ef7..2a45a25e42fb 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7532,6 +7532,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) intel_atomic_commit_fence_wait(state); drm_atomic_helper_wait_for_dependencies(&state->base); + drm_dp_mst_atomic_wait_for_dependencies(&state->base); if (state->modeset) wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); @@ -8600,6 +8601,10 @@ out: return ret; } +static const struct drm_mode_config_helper_funcs intel_mode_config_funcs = { + .atomic_commit_setup = drm_dp_mst_atomic_setup_commit, +}; + static void intel_mode_config_init(struct drm_i915_private *i915) { struct drm_mode_config *mode_config = &i915->drm.mode_config; @@ -8614,6 +8619,7 @@ static void intel_mode_config_init(struct drm_i915_private *i915) mode_config->prefer_shadow = 1; mode_config->funcs = &intel_mode_funcs; + mode_config->helper_private = &intel_mode_config_funcs; mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915); |