Commit 869e188a authored by Daniel Vetter's avatar Daniel Vetter

drm: Fix locking in drm_atomic_helper_resume

In the conversion to drop drm_modeset_lock_all and the magic implicit
context I failed to realize that _resume starts out with a pile of
state copies, but not with the locks. And hence drm_atomic_commit
won't grab these for us.

v2: Add locking checks in helpers to make sure we catch this in the
future. Note we can only require the locks in the atomic_check phase,
not in the commit phase. But since any commit is guaranteed to first
run the checks (even for the resume stuff where we use stored
duplicated old state) this should give us full coverage. Requested by
Maarten.

Cc: Jyri Sarha <jsarha@ti.com>
Fixes: a5b8444e ("drm/atomic-helper: remove modeset_lock_all from helper_resume")
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170531083813.1390-1-daniel.vetter@ffwll.ch
parent efd11cc8
...@@ -508,6 +508,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -508,6 +508,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
bool has_connectors = bool has_connectors =
!!new_crtc_state->connector_mask; !!new_crtc_state->connector_mask;
WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) { if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) {
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n", DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n",
crtc->base.id, crtc->name); crtc->base.id, crtc->name);
...@@ -551,6 +553,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, ...@@ -551,6 +553,8 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) { for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
const struct drm_connector_helper_funcs *funcs = connector->helper_private; const struct drm_connector_helper_funcs *funcs = connector->helper_private;
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
/* /*
* This only sets crtc->connectors_changed for routing changes, * This only sets crtc->connectors_changed for routing changes,
* drivers must set crtc->connectors_changed themselves when * drivers must set crtc->connectors_changed themselves when
...@@ -650,6 +654,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev, ...@@ -650,6 +654,8 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
const struct drm_plane_helper_funcs *funcs; const struct drm_plane_helper_funcs *funcs;
WARN_ON(!drm_modeset_is_locked(&plane->mutex));
funcs = plane->helper_private; funcs = plane->helper_private;
drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane); drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane);
...@@ -2663,7 +2669,12 @@ int drm_atomic_helper_resume(struct drm_device *dev, ...@@ -2663,7 +2669,12 @@ int drm_atomic_helper_resume(struct drm_device *dev,
drm_modeset_acquire_init(&ctx, 0); drm_modeset_acquire_init(&ctx, 0);
while (1) { while (1) {
err = drm_modeset_lock_all_ctx(dev, &ctx);
if (err)
goto out;
err = drm_atomic_helper_commit_duplicated_state(state, &ctx); err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
out:
if (err != -EDEADLK) if (err != -EDEADLK)
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment