[RFCv3 02/14] drm: convert crtc to ww_mutex
Rob Clark
robdclark at gmail.com
Wed Nov 20 12:48:01 PST 2013
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
More information about the dri-devel
mailing list