[PATCH] drm/kms: Convert mode_config's mutex to an rwsem
Adam Jackson
ajax at redhat.com
Thu Jun 21 11:51:33 PDT 2012
This is a start at pushing down the locking a bit further. Ideally
things like i2c shouldn't affect pageflipping. I've made some attempt
to only take read locks where possible, but there's certainly more work
to be done.
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
drivers/gpu/drm/ast/ast_drv.c | 4 +-
drivers/gpu/drm/drm_crtc.c | 133 +++++++++++++++--------------
drivers/gpu/drm/drm_crtc_helper.c | 5 +-
drivers/gpu/drm/drm_fb_helper.c | 20 ++--
drivers/gpu/drm/drm_sysfs.c | 8 +-
drivers/gpu/drm/exynos/exynos_drm_plane.c | 4 +-
drivers/gpu/drm/gma500/psb_device.c | 8 +-
drivers/gpu/drm/gma500/psb_drv.c | 4 +-
drivers/gpu/drm/i915/i915_debugfs.c | 25 ++----
drivers/gpu/drm/i915/i915_drv.c | 4 +-
drivers/gpu/drm/i915/i915_irq.c | 4 +-
drivers/gpu/drm/i915/intel_dp.c | 4 +-
drivers/gpu/drm/i915/intel_fb.c | 4 +-
drivers/gpu/drm/i915/intel_lvds.c | 4 +-
drivers/gpu/drm/i915/intel_overlay.c | 20 +++--
drivers/gpu/drm/i915/intel_sprite.c | 8 +-
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | 12 ++--
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 15 ++--
include/drm/drm_crtc.h | 4 +-
19 files changed, 143 insertions(+), 147 deletions(-)
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index d0c4574..cea85a9 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -96,9 +96,9 @@ static int ast_drm_thaw(struct drm_device *dev)
ast_post_gpu(dev);
drm_mode_config_reset(dev);
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
drm_helper_resume_force_mode(dev);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
console_lock();
ast_fbdev_set_suspend(dev, 0);
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 08a7aa7..6f57547 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -378,7 +378,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
crtc->dev = dev;
crtc->funcs = funcs;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
if (ret)
@@ -390,7 +390,7 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
dev->mode_config.num_crtc++;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -479,7 +479,7 @@ int drm_connector_init(struct drm_device *dev,
{
int ret;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
if (ret)
@@ -508,7 +508,7 @@ int drm_connector_init(struct drm_device *dev,
dev->mode_config.dpms_property, 0);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -537,11 +537,11 @@ void drm_connector_cleanup(struct drm_connector *connector)
list_for_each_entry_safe(mode, t, &connector->user_modes, head)
drm_mode_remove(connector, mode);
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
drm_mode_object_put(dev, &connector->base);
list_del(&connector->head);
dev->mode_config.num_connector--;
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
EXPORT_SYMBOL(drm_connector_cleanup);
@@ -563,7 +563,7 @@ int drm_encoder_init(struct drm_device *dev,
{
int ret;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
if (ret)
@@ -577,7 +577,7 @@ int drm_encoder_init(struct drm_device *dev,
dev->mode_config.num_encoder++;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -586,11 +586,11 @@ EXPORT_SYMBOL(drm_encoder_init);
void drm_encoder_cleanup(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
drm_mode_object_put(dev, &encoder->base);
list_del(&encoder->head);
dev->mode_config.num_encoder--;
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
EXPORT_SYMBOL(drm_encoder_cleanup);
@@ -602,7 +602,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
{
int ret;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
if (ret)
@@ -636,7 +636,7 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
}
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -646,7 +646,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
{
struct drm_device *dev = plane->dev;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
kfree(plane->format_types);
drm_mode_object_put(dev, &plane->base);
/* if not added to a list, it must be a private plane */
@@ -654,7 +654,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
list_del(&plane->head);
dev->mode_config.num_plane--;
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
EXPORT_SYMBOL(drm_plane_cleanup);
@@ -927,7 +927,7 @@ EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
*/
void drm_mode_config_init(struct drm_device *dev)
{
- mutex_init(&dev->mode_config.mutex);
+ init_rwsem(&dev->mode_config.sem);
mutex_init(&dev->mode_config.idr_mutex);
INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list);
@@ -938,9 +938,9 @@ void drm_mode_config_init(struct drm_device *dev)
INIT_LIST_HEAD(&dev->mode_config.plane_list);
idr_init(&dev->mode_config.crtc_idr);
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
drm_mode_create_standard_connector_properties(dev);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
/* Just to be sure */
dev->mode_config.num_fb = 0;
@@ -1169,7 +1169,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
/*
* For the non-control nodes we need to limit the list of resources
@@ -1311,7 +1311,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
card_res->count_connectors, card_res->count_encoders);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1343,7 +1343,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, crtc_resp->crtc_id,
DRM_MODE_OBJECT_CRTC);
@@ -1371,7 +1371,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
}
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1418,7 +1418,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
DRM_DEBUG_KMS("[CONNECTOR:%d:?]\n", out_resp->connector_id);
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, out_resp->connector_id,
DRM_MODE_OBJECT_CONNECTOR);
@@ -1442,6 +1442,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
dev->mode_config.max_height);
}
+ downgrade_write(&dev->mode_config.sem);
+
/* delayed so we get modes regardless of pre-fill_modes state */
list_for_each_entry(mode, &connector->modes, head)
mode_count++;
@@ -1515,7 +1517,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
out_resp->count_encoders = encoders_count;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1530,7 +1532,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, enc_resp->encoder_id,
DRM_MODE_OBJECT_ENCODER);
if (!obj) {
@@ -1549,7 +1551,7 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
enc_resp->possible_clones = encoder->possible_clones;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1576,7 +1578,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
config = &dev->mode_config;
/*
@@ -1598,7 +1600,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
plane_resp->count_planes = config->num_plane;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1626,7 +1628,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, plane_resp->plane_id,
DRM_MODE_OBJECT_PLANE);
if (!obj) {
@@ -1666,7 +1668,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
plane_resp->count_format_types = plane->format_count;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1697,7 +1699,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
/*
* First, find the plane, crtc, and fb objects. If not available,
@@ -1796,7 +1798,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
}
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1840,7 +1842,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
return -ERANGE;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, crtc_req->crtc_id,
DRM_MODE_OBJECT_CRTC);
if (!obj) {
@@ -1966,7 +1968,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
out:
kfree(connector_set);
drm_mode_destroy(dev, mode);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1984,7 +1986,8 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
if (!req->flags)
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ /* XXX should probaby be down_read */
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, req->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
DRM_DEBUG_KMS("Unknown CRTC ID %d\n", req->crtc_id);
@@ -2012,7 +2015,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
}
}
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2095,7 +2098,7 @@ int drm_mode_addfb(struct drm_device *dev,
if ((config->min_height > r.height) || (r.height > config->max_height))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
/* TODO check buffer is sufficiently large */
/* TODO setup destructor callback */
@@ -2112,7 +2115,7 @@ int drm_mode_addfb(struct drm_device *dev,
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2269,7 +2272,7 @@ int drm_mode_addfb2(struct drm_device *dev,
if (ret)
return ret;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
fb = dev->mode_config.funcs->fb_create(dev, file_priv, r);
if (IS_ERR(fb)) {
@@ -2283,7 +2286,7 @@ int drm_mode_addfb2(struct drm_device *dev,
DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2317,7 +2320,7 @@ int drm_mode_rmfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, *id, DRM_MODE_OBJECT_FB);
/* TODO check that we really get a framebuffer back. */
if (!obj) {
@@ -2342,7 +2345,7 @@ int drm_mode_rmfb(struct drm_device *dev,
fb->funcs->destroy(fb);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2374,7 +2377,7 @@ int drm_mode_getfb(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
if (!obj) {
ret = -EINVAL;
@@ -2390,7 +2393,7 @@ int drm_mode_getfb(struct drm_device *dev,
fb->funcs->create_handle(fb, file_priv, &r->handle);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2409,7 +2412,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, r->fb_id, DRM_MODE_OBJECT_FB);
if (!obj) {
ret = -EINVAL;
@@ -2463,7 +2466,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
out_err2:
kfree(clips);
out_err1:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2487,12 +2490,12 @@ void drm_fb_release(struct drm_file *priv)
struct drm_device *dev = priv->minor->dev;
struct drm_framebuffer *fb, *tfb;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
list_del(&fb->filp_head);
fb->funcs->destroy(fb);
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
/**
@@ -2608,7 +2611,7 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
@@ -2632,7 +2635,7 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
drm_mode_attachmode(dev, connector, mode);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2662,7 +2665,7 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, mode_cmd->connector_id, DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
@@ -2679,7 +2682,7 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
ret = drm_mode_detachmode(dev, connector, &mode);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -2946,7 +2949,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, out_resp->prop_id, DRM_MODE_OBJECT_PROPERTY);
if (!obj) {
ret = -EINVAL;
@@ -3024,7 +3027,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev,
out_resp->count_enum_blobs = blob_count;
}
done:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -3075,7 +3078,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, out_resp->blob_id, DRM_MODE_OBJECT_BLOB);
if (!obj) {
ret = -EINVAL;
@@ -3093,7 +3096,7 @@ int drm_mode_getblob_ioctl(struct drm_device *dev,
out_resp->length = blob->length;
done:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -3230,7 +3233,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
if (!obj) {
@@ -3267,7 +3270,7 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
}
arg->count_props = props_count;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -3284,7 +3287,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
arg_obj = drm_mode_object_find(dev, arg->obj_id, arg->obj_type);
if (!arg_obj)
@@ -3322,7 +3325,7 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
}
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -3384,7 +3387,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
ret = -EINVAL;
@@ -3425,7 +3428,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -3443,7 +3446,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, crtc_lut->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj) {
ret = -EINVAL;
@@ -3476,7 +3479,7 @@ int drm_mode_gamma_get_ioctl(struct drm_device *dev,
goto out;
}
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -3495,7 +3498,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
page_flip->reserved != 0)
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, page_flip->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!obj)
goto out;
@@ -3568,7 +3571,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
}
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 3252e70..69cbf88 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -930,7 +930,8 @@ static void output_poll_execute(struct work_struct *work)
if (!drm_kms_helper_poll)
return;
- mutex_lock(&dev->mode_config.mutex);
+ /* XXX need to sort this so it can be down_read */
+ down_write(&dev->mode_config.sem);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
/* if this is HPD or polled don't check it -
@@ -958,7 +959,7 @@ static void output_poll_execute(struct work_struct *work)
changed = true;
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
if (changed) {
/* send a uevent + call fbdev */
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 5683b7f..d173c27 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -320,7 +320,7 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
/*
* For each CRTC in this fb, turn the connectors on/off.
*/
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
@@ -335,7 +335,7 @@ static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
dev->mode_config.dpms_property, dpms_mode);
}
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
int drm_fb_helper_blank(int blank, struct fb_info *info)
@@ -655,16 +655,16 @@ int drm_fb_helper_set_par(struct fb_info *info)
return -EINVAL;
}
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set);
if (ret) {
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
if (fb_helper->delayed_hotplug) {
fb_helper->delayed_hotplug = false;
@@ -684,7 +684,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
int ret = 0;
int i;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
@@ -701,7 +701,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
}
}
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
EXPORT_SYMBOL(drm_fb_helper_pan_display);
@@ -1359,7 +1359,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
if (!fb_helper->fb)
return 0;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (crtc->fb)
crtcs_bound = true;
@@ -1369,7 +1369,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
if (!bound && crtcs_bound) {
fb_helper->delayed_hotplug = true;
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
DRM_DEBUG_KMS("\n");
@@ -1381,7 +1381,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
max_height);
drm_setup_crtcs(fb_helper);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
}
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 45cf1dd..4947d86 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -159,14 +159,12 @@ static ssize_t status_show(struct device *device,
{
struct drm_connector *connector = to_drm_connector(device);
enum drm_connector_status status;
- int ret;
- ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex);
- if (ret)
- return ret;
+ if (!down_write_trylock(&connector->dev->mode_config.sem))
+ return -EINTR;
status = connector->funcs->detect(connector, true);
- mutex_unlock(&connector->dev->mode_config.mutex);
+ up_write(&connector->dev->mode_config.sem);
return snprintf(buf, PAGE_SIZE, "%s\n",
drm_get_connector_status_name(status));
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index c4c6525..e083309 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -149,7 +149,7 @@ int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
}
}
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, zpos_req->plane_id,
DRM_MODE_OBJECT_PLANE);
@@ -166,6 +166,6 @@ int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
exynos_plane->overlay.zpos = zpos_req->zpos;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
index eff039b..549407c 100644
--- a/drivers/gpu/drm/gma500/psb_device.c
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -190,7 +190,7 @@ static int psb_save_display_registers(struct drm_device *dev)
regs->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
/* Save crtc and output state */
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
if (drm_helper_crtc_in_use(crtc))
crtc->funcs->save(crtc);
@@ -200,7 +200,7 @@ static int psb_save_display_registers(struct drm_device *dev)
if (connector->funcs->save)
connector->funcs->save(connector);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
@@ -230,7 +230,7 @@ static int psb_restore_display_registers(struct drm_device *dev)
/*make sure VGA plane is off. it initializes to on after reset!*/
PSB_WVDC32(0x80000000, VGACNTRL);
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
if (drm_helper_crtc_in_use(crtc))
crtc->funcs->restore(crtc);
@@ -239,7 +239,7 @@ static int psb_restore_display_registers(struct drm_device *dev)
if (connector->funcs->restore)
connector->funcs->restore(connector);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index caba6e0..ca04805 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -475,7 +475,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
case PSB_MODE_OPERATION_MODE_VALID:
umode = &arg->mode;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, obj_id,
DRM_MODE_OBJECT_CONNECTOR);
@@ -524,7 +524,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
if (mode)
drm_mode_destroy(dev, mode);
mode_op_out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
default:
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 5363e9c..4a1c145 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1362,11 +1362,9 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
drm_i915_private_t *dev_priv = dev->dev_private;
struct intel_fbdev *ifbdev;
struct intel_framebuffer *fb;
- int ret;
- ret = mutex_lock_interruptible(&dev->mode_config.mutex);
- if (ret)
- return ret;
+ if (!down_read_trylock(&dev->mode_config.sem))
+ return -EINTR;
ifbdev = dev_priv->fbdev;
fb = to_intel_framebuffer(ifbdev->helper.fb);
@@ -1392,7 +1390,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
seq_printf(m, "\n");
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
@@ -1402,11 +1400,9 @@ static int i915_context_status(struct seq_file *m, void *unused)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
- int ret;
- ret = mutex_lock_interruptible(&dev->mode_config.mutex);
- if (ret)
- return ret;
+ if (!down_read_trylock(&dev->mode_config.sem))
+ return -EINTR;
if (dev_priv->pwrctx) {
seq_printf(m, "power context ");
@@ -1420,7 +1416,7 @@ static int i915_context_status(struct seq_file *m, void *unused)
seq_printf(m, "\n");
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
@@ -1545,17 +1541,14 @@ static int i915_dpio_info(struct seq_file *m, void *data)
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- int ret;
-
if (!IS_VALLEYVIEW(dev)) {
seq_printf(m, "unsupported\n");
return 0;
}
- ret = mutex_lock_interruptible(&dev->mode_config.mutex);
- if (ret)
- return ret;
+ if (!down_read_trylock(&dev->mode_config.sem))
+ return -EINTR;
seq_printf(m, "DPIO_CTL: 0x%08x\n", I915_READ(DPIO_CTL));
@@ -1582,7 +1575,7 @@ static int i915_dpio_info(struct seq_file *m, void *data)
seq_printf(m, "DPIO_FASTCLK_DISABLE: 0x%08x\n",
intel_dpio_read(dev_priv, DPIO_FASTCLK_DISABLE));
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 9fe9ebe..a632117 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -651,9 +651,9 @@ static int i915_drm_thaw(struct drm_device *dev)
drm_irq_install(dev);
/* Resume the modeset for every activated CRTC */
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
drm_helper_resume_force_mode(dev);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
intel_opregion_init(dev);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b1fe0ed..2e589b2 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -283,14 +283,14 @@ static void i915_hotplug_work_func(struct work_struct *work)
struct drm_mode_config *mode_config = &dev->mode_config;
struct intel_encoder *encoder;
- mutex_lock(&mode_config->mutex);
+ down_write(&mode_config->sem);
DRM_DEBUG_KMS("running encoder hotplug functions\n");
list_for_each_entry(encoder, &mode_config->encoder_list, base.head)
if (encoder->hot_plug)
encoder->hot_plug(encoder);
- mutex_unlock(&mode_config->mutex);
+ up_write(&mode_config->sem);
/* Just fire off a uevent and let userspace tell us what to do */
drm_helper_hpd_irq_event(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index c044932..f2c8a93 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1087,9 +1087,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work)
struct intel_dp, panel_vdd_work);
struct drm_device *dev = intel_dp->base.base.dev;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
ironlake_panel_vdd_off_sync(intel_dp);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync)
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index bf86907..bacbbd4 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -279,7 +279,7 @@ void intel_fb_restore_mode(struct drm_device *dev)
struct drm_mode_config *config = &dev->mode_config;
struct drm_plane *plane;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper);
if (ret)
@@ -289,5 +289,5 @@ void intel_fb_restore_mode(struct drm_device *dev)
list_for_each_entry(plane, &config->plane_list, head)
plane->funcs->disable_plane(plane);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 08eb04c..5e900d9 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -539,9 +539,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
dev_priv->modeset_on_lid = 0;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
drm_helper_resume_force_mode(dev);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return NOTIFY_OK;
}
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 458743d..3856757 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -779,7 +779,6 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
u32 swidth, swidthsw, sheight, ostride;
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
- BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
BUG_ON(!overlay);
ret = intel_overlay_release_old_vid(overlay);
@@ -884,7 +883,6 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
int ret;
BUG_ON(!mutex_is_locked(&dev->struct_mutex));
- BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
ret = intel_overlay_recover_from_interrupt(overlay);
if (ret != 0)
@@ -1136,13 +1134,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
}
if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) {
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
mutex_lock(&dev->struct_mutex);
ret = intel_overlay_switch_off(overlay);
mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1166,7 +1164,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
goto out_free;
}
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
mutex_lock(&dev->struct_mutex);
if (new_bo->tiling_mode) {
@@ -1248,7 +1246,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
goto out_unlock;
mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
kfree(params);
@@ -1256,7 +1254,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
out_unlock:
mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
drm_gem_object_unreference_unlocked(&new_bo->base);
out_free:
kfree(params);
@@ -1324,6 +1322,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
struct intel_overlay *overlay;
struct overlay_registers __iomem *regs;
int ret;
+ bool write = !!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS);
/* No need to check for DRIVER_MODESET - we don't set it up then. */
overlay = dev_priv->overlay;
@@ -1332,7 +1331,10 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
return -ENODEV;
}
- mutex_lock(&dev->mode_config.mutex);
+ if (write)
+ down_write(&dev->mode_config.sem);
+ else
+ down_read(&dev->mode_config.sem);
mutex_lock(&dev->struct_mutex);
ret = -EINVAL;
@@ -1398,7 +1400,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
ret = 0;
out_unlock:
mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 2a20fb0..b7226d8 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -570,7 +570,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
return -EINVAL;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE);
if (!obj) {
@@ -583,7 +583,7 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
ret = intel_plane->update_colorkey(plane, set);
out_unlock:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -599,7 +599,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -ENODEV;
- mutex_lock(&dev->mode_config.mutex);
+ down_read(&dev->mode_config.sem);
obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE);
if (!obj) {
@@ -612,7 +612,7 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
intel_plane->get_colorkey(plane, get);
out_unlock:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index 66917c6..820e694 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -160,8 +160,8 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
goto out_no_copy;
}
- ret = mutex_lock_interruptible(&dev->mode_config.mutex);
- if (unlikely(ret != 0)) {
+ ret = down_write_trylock(&dev->mode_config.sem);
+ if (unlikely(ret == 0)) {
ret = -ERESTARTSYS;
goto out_no_mode_mutex;
}
@@ -195,7 +195,7 @@ out_no_surface:
ttm_read_unlock(&vmaster->lock);
out_no_ttm_lock:
out_no_fb:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
out_no_mode_mutex:
out_no_copy:
kfree(clips);
@@ -246,8 +246,8 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
goto out_no_copy;
}
- ret = mutex_lock_interruptible(&dev->mode_config.mutex);
- if (unlikely(ret != 0)) {
+ ret = down_write_trylock(&dev->mode_config.sem);
+ if (unlikely(ret == 0)) {
ret = -ERESTARTSYS;
goto out_no_mode_mutex;
}
@@ -277,7 +277,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
ttm_read_unlock(&vmaster->lock);
out_no_ttm_lock:
out_no_fb:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
out_no_mode_mutex:
out_no_copy:
kfree(clips);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 6b0078f..b053b3b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -352,7 +352,7 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
struct vmw_display_unit *du;
struct drm_crtc *crtc;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
du = vmw_crtc_to_du(crtc);
@@ -366,7 +366,7 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
64, 64, du->hotspot_x, du->hotspot_y);
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
}
/*
@@ -1469,8 +1469,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
struct drm_crtc *crtc;
int ret = 0;
-
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
if (arg->flags & DRM_VMW_CURSOR_BYPASS_ALL) {
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -1479,7 +1478,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
du->hotspot_y = arg->yhot;
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
@@ -1496,7 +1495,7 @@ int vmw_kms_cursor_bypass_ioctl(struct drm_device *dev, void *data,
du->hotspot_y = arg->yhot;
out:
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return ret;
}
@@ -1646,7 +1645,7 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
struct vmw_display_unit *du;
struct drm_connector *con;
- mutex_lock(&dev->mode_config.mutex);
+ down_write(&dev->mode_config.sem);
#if 0
{
@@ -1676,7 +1675,7 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
con->status = vmw_du_connector_detect(con, true);
}
- mutex_unlock(&dev->mode_config.mutex);
+ up_write(&dev->mode_config.sem);
return 0;
}
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index bac55c2..84763f5 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -728,7 +728,7 @@ struct drm_mode_group {
/**
* drm_mode_config - Mode configuration control structure
- * @mutex: mutex protecting KMS related lists and structures
+ * @sem: r/w semaphore protecting KMS related lists and structures
* @idr_mutex: mutex for KMS ID allocation and management
* @crtc_idr: main KMS ID tracking object
* @num_fb: number of fbs available
@@ -754,7 +754,7 @@ struct drm_mode_group {
* global restrictions are also here, e.g. dimension restrictions.
*/
struct drm_mode_config {
- struct mutex mutex; /* protects configuration (mode lists etc.) */
+ struct rw_semaphore sem; /* protects configuration (mode lists etc.) */
struct mutex idr_mutex; /* for IDR management */
struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
/* this is limited to one for now */
--
1.7.7.6
More information about the dri-devel
mailing list