TODO possibly just squash this back into "convert crtc/plane to atomic".. This reintroduces drm_modeset_lock_all() in a places that had not been converted to more fine grained locking (setcrtc, setplane, etc). This makes the locking equivalent to before. Note that since mode_config.mutex is a drm_modeset_lock, the lock is automatically dropped at the end of the atomic update. Signed-off-by: Rob Clark <robdclark@xxxxxxxxx> --- drivers/gpu/drm/drm_crtc.c | 21 +++++++++++++++++++++ drivers/gpu/drm/drm_fb_helper.c | 18 +++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 972af76..4e3b527 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -709,14 +709,22 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) * in this manner. */ if (atomic_read(&fb->refcount.refcount) > 1) { + struct drm_mode_config *config = &dev->mode_config; struct drm_atomic_state *state; + int ret; +retry: state = dev->driver->atomic_begin(dev, 0); if (IS_ERR(state)) { DRM_ERROR("failed to disable crtc and/or plane when fb was deleted\n"); return; } + ret = drm_modeset_lock(&config->mutex, &state->acquire_ctx) || + drm_modeset_lock_all_crtcs(dev, &state->acquire_ctx); + if (ret) + goto out; + /* remove from any plane */ list_for_each_entry(plane, &dev->mode_config.plane_list, head) { if (plane->fb == fb) @@ -729,7 +737,10 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) else dev->driver->atomic_commit(dev, state); +out: dev->driver->atomic_end(dev, state); + if (ret == -EDEADLK) + goto retry; } drm_framebuffer_unreference(fb); @@ -2595,6 +2606,11 @@ retry: if (IS_ERR(state)) return PTR_ERR(state); + ret = drm_modeset_lock(&config->mutex, &state->acquire_ctx) || + drm_modeset_lock_all_crtcs(dev, &state->acquire_ctx); + if (ret) + goto out; + plane = drm_plane_find(dev, plane_req->plane_id); if (!plane) { DRM_DEBUG_KMS("Unknown plane ID %d\n", @@ -2810,6 +2826,11 @@ retry: if (IS_ERR(state)) return PTR_ERR(state); + ret = drm_modeset_lock(&config->mutex, &state->acquire_ctx) || + drm_modeset_lock_all_crtcs(dev, &state->acquire_ctx); + if (ret) + goto out; + /* If connectors change, we need to check if we need to steal one * from another CRTC.. setcrtc makes this implicit, but atomic * treats it as an error so we need to handle here: diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 3815e1a..4dc22cf 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -36,6 +36,7 @@ #include <linux/module.h> #include <drm/drmP.h> #include <drm/drm_crtc.h> +#include <drm/drm_atomic.h> #include <drm/drm_fb_helper.h> #include <drm/drm_crtc_helper.h> @@ -287,11 +288,13 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper, bool lockless) { struct drm_device *dev = fb_helper->dev; + struct drm_mode_config *config = &dev->mode_config; struct drm_plane *plane; bool error = false; struct drm_atomic_state *state; - int i; + int ret, i; +retry: state = dev->driver->atomic_begin(dev, lockless ? DRM_MODE_ATOMIC_NOLOCK : 0); if (IS_ERR(state)) { @@ -299,6 +302,11 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper, return true; } + ret = drm_modeset_lock(&config->mutex, &state->acquire_ctx) || + drm_modeset_lock_all_crtcs(dev, &state->acquire_ctx); + if (ret) + goto out; + list_for_each_entry(plane, &dev->mode_config.plane_list, head) if (plane->type != DRM_PLANE_TYPE_PRIMARY) drm_plane_force_disable(plane, state); @@ -309,7 +317,12 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper, else dev->driver->atomic_commit(dev, state); +out: dev->driver->atomic_end(dev, state); + if (ret == -EDEADLK) + goto retry; + + drm_modeset_lock_all(dev); for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; @@ -326,6 +339,9 @@ bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper, if (ret) error = true; } + + drm_modeset_unlock_all(dev); + return error; } EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode); -- 1.9.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel