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@xxxxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel