At the moment, this doesn't do anything. But for atomic we will have an ww_acquire_ctx associated with the state, to simplify the locking and avoid potential deadlock when we cannot control the locking order. --- drivers/gpu/drm/drm_crtc.c | 20 +++++++++++--------- drivers/gpu/drm/i915/intel_display.c | 16 ++++++++-------- drivers/gpu/drm/omapdrm/omap_crtc.c | 10 +++++----- drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 12 ++++++++---- include/drm/drm_crtc.h | 3 ++- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 81ac351..55f37db 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -52,7 +52,7 @@ void drm_modeset_lock_all(struct drm_device *dev) mutex_lock(&dev->mode_config.mutex); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex); + mutex_lock_nest_lock(&crtc->mutex.base, &dev->mode_config.mutex); } EXPORT_SYMBOL(drm_modeset_lock_all); @@ -65,7 +65,7 @@ void drm_modeset_unlock_all(struct drm_device *dev) struct drm_crtc *crtc; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); mutex_unlock(&dev->mode_config.mutex); } @@ -84,7 +84,7 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) return; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - WARN_ON(!mutex_is_locked(&crtc->mutex)); + WARN_ON(!ww_mutex_is_locked(&crtc->mutex)); WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); } @@ -613,6 +613,8 @@ void drm_framebuffer_remove(struct drm_framebuffer *fb) } EXPORT_SYMBOL(drm_framebuffer_remove); +static DEFINE_WW_CLASS(crtc_ww_class); + /** * drm_crtc_init - Initialise a new CRTC object * @dev: DRM device @@ -634,8 +636,8 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, crtc->invert_dimensions = false; drm_modeset_lock_all(dev); - mutex_init(&crtc->mutex); - mutex_lock_nest_lock(&crtc->mutex, &dev->mode_config.mutex); + ww_mutex_init(&crtc->mutex, &crtc_ww_class); + mutex_lock_nest_lock(&crtc->mutex.base, &dev->mode_config.mutex); ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); if (ret) @@ -2284,7 +2286,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, } crtc = obj_to_crtc(obj); - mutex_lock(&crtc->mutex); + ww_mutex_lock(&crtc->mutex, NULL); if (req->flags & DRM_MODE_CURSOR_BO) { if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { ret = -ENXIO; @@ -2308,7 +2310,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, } } out: - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); return ret; @@ -3657,7 +3659,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, return -ENOENT; crtc = obj_to_crtc(obj); - mutex_lock(&crtc->mutex); + ww_mutex_lock(&crtc->mutex, NULL); if (crtc->fb == NULL) { /* The framebuffer is currently unbound, presumably * due to a hotplug event, that userspace has not @@ -3741,7 +3743,7 @@ out: drm_framebuffer_unreference(fb); if (old_fb) drm_framebuffer_unreference(old_fb); - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); return ret; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3cddd50..741188f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2232,11 +2232,11 @@ void intel_display_handle_reset(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - mutex_lock(&crtc->mutex); + ww_mutex_lock(&crtc->mutex, NULL); if (intel_crtc->active) dev_priv->display.update_plane(crtc, crtc->fb, crtc->x, crtc->y); - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); } } @@ -7550,7 +7550,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, if (encoder->crtc) { crtc = encoder->crtc; - mutex_lock(&crtc->mutex); + ww_mutex_lock(&crtc->mutex, NULL); old->dpms_mode = connector->dpms; old->load_detect_temp = false; @@ -7581,7 +7581,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, return false; } - mutex_lock(&crtc->mutex); + ww_mutex_lock(&crtc->mutex, NULL); intel_encoder->new_crtc = to_intel_crtc(crtc); to_intel_connector(connector)->new_encoder = intel_encoder; @@ -7609,7 +7609,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n"); if (IS_ERR(fb)) { DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n"); - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); return false; } @@ -7617,7 +7617,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); if (old->release_fb) old->release_fb->funcs->destroy(old->release_fb); - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); return false; } @@ -7648,7 +7648,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, drm_framebuffer_unreference(old->release_fb); } - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); return; } @@ -7656,7 +7656,7 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, if (old->dpms_mode != DRM_MODE_DPMS_ON) connector->funcs->dpms(connector, old->dpms_mode); - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); } static int i9xx_pll_refclk(struct drm_device *dev, diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 5dd22ab..c09d29f 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -307,13 +307,13 @@ static void page_flip_worker(struct work_struct *work) struct drm_display_mode *mode = &crtc->mode; struct drm_gem_object *bo; - mutex_lock(&crtc->mutex); + ww_mutex_lock(&crtc->mutex, NULL); omap_plane_mode_set(omap_crtc->plane, crtc, crtc->fb, 0, 0, mode->hdisplay, mode->vdisplay, crtc->x << 16, crtc->y << 16, mode->hdisplay << 16, mode->vdisplay << 16, vblank_cb, crtc); - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); bo = omap_framebuffer_bo(crtc->fb, 0); drm_gem_object_unreference_unlocked(bo); @@ -447,7 +447,7 @@ static void apply_worker(struct work_struct *work) * the callbacks and list modification all serialized * with respect to modesetting ioctls from userspace. */ - mutex_lock(&crtc->mutex); + ww_mutex_lock(&crtc->mutex, NULL); dispc_runtime_get(); /* @@ -492,7 +492,7 @@ static void apply_worker(struct work_struct *work) out: dispc_runtime_put(); - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); } int omap_crtc_apply(struct drm_crtc *crtc, @@ -500,7 +500,7 @@ int omap_crtc_apply(struct drm_crtc *crtc, { struct omap_crtc *omap_crtc = to_omap_crtc(crtc); - WARN_ON(!mutex_is_locked(&crtc->mutex)); + WARN_ON(!ww_mutex_is_locked(&crtc->mutex)); /* no need to queue it again if it is already queued: */ if (apply->queued) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index f91447c..7b3bf18 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -186,7 +186,7 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, * can do this since the caller in the drm core doesn't check anything * which is protected by any looks. */ - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); drm_modeset_lock_all(dev_priv->dev); /* A lot of the code assumes this */ @@ -251,7 +251,9 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, ret = 0; out: drm_modeset_unlock_all(dev_priv->dev); - mutex_lock(&crtc->mutex); +// XXX umm, we probably need the state object here to properly +// re-aquire the lock.. + ww_mutex_lock(&crtc->mutex, NULL); return ret; } @@ -272,7 +274,7 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) * can do this since the caller in the drm core doesn't check anything * which is protected by any looks. */ - mutex_unlock(&crtc->mutex); + ww_mutex_unlock(&crtc->mutex); drm_modeset_lock_all(dev_priv->dev); vmw_cursor_update_position(dev_priv, shown, @@ -280,7 +282,9 @@ int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) du->cursor_y + du->hotspot_y); drm_modeset_unlock_all(dev_priv->dev); - mutex_lock(&crtc->mutex); +// XXX umm, we probably need the state object here to properly +// re-aquire the lock.. + ww_mutex_lock(&crtc->mutex, NULL); return 0; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 0ca684a..3650254 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -27,6 +27,7 @@ #include <linux/i2c.h> #include <linux/spinlock.h> +#include <linux/ww_mutex.h> #include <linux/types.h> #include <linux/idr.h> #include <linux/fb.h> @@ -417,7 +418,7 @@ struct drm_crtc { * state, ...) and a write lock for everything which can be update * without a full modeset (fb, cursor data, ...) */ - struct mutex mutex; + struct ww_mutex mutex; struct drm_mode_object base; -- 1.8.4.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel