This prevents a race between module init and sysfs access (usually only seen at module reload time, or if somehow your userspace starts fast enough and pokes at /sys/class/drm while the drivers are still initializing). Signed-off-by: Jesse Barnes <jbarnes@xxxxxxxxxxxxxxxx> --- drivers/gpu/drm/drm_sysfs.c | 75 ++++++++++++++++++++++++++++++------------ 1 files changed, 53 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 0f9ef9b..bb8bbc3 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -161,15 +161,20 @@ static ssize_t status_show(struct device *device, enum drm_connector_status status; int ret; + mutex_lock(&drm_global_mutex); + ret = mutex_lock_interruptible(&connector->dev->mode_config.mutex); if (ret) - return ret; + goto out; status = connector->funcs->detect(connector, true); mutex_unlock(&connector->dev->mode_config.mutex); - return snprintf(buf, PAGE_SIZE, "%s\n", - drm_get_connector_status_name(status)); + ret = snprintf(buf, PAGE_SIZE, "%s\n", + drm_get_connector_status_name(status)); +out: + mutex_unlock(&drm_global_mutex); + return ret; } static ssize_t dpms_show(struct device *device, @@ -181,14 +186,20 @@ static ssize_t dpms_show(struct device *device, uint64_t dpms_status; int ret; + mutex_lock(&drm_global_mutex); ret = drm_connector_property_get_value(connector, dev->mode_config.dpms_property, &dpms_status); - if (ret) - return 0; + if (ret) { + ret = 0; + goto out; + } - return snprintf(buf, PAGE_SIZE, "%s\n", + ret = snprintf(buf, PAGE_SIZE, "%s\n", drm_get_dpms_name((int)dpms_status)); +out: + mutex_unlock(&drm_global_mutex); + return ret; } static ssize_t enabled_show(struct device *device, @@ -196,9 +207,13 @@ static ssize_t enabled_show(struct device *device, char *buf) { struct drm_connector *connector = to_drm_connector(device); + int ret; - return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" : - "disabled"); + mutex_lock(&drm_global_mutex); + ret = snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" : + "disabled"); + mutex_unlock(&drm_global_mutex); + return ret; } static ssize_t edid_show(struct file *filp, struct kobject *kobj, @@ -210,21 +225,30 @@ static ssize_t edid_show(struct file *filp, struct kobject *kobj, unsigned char *edid; size_t size; - if (!connector->edid_blob_ptr) - return 0; + mutex_lock(&drm_global_mutex); + if (!connector->edid_blob_ptr) { + count = 0; + goto out; + } edid = connector->edid_blob_ptr->data; size = connector->edid_blob_ptr->length; - if (!edid) - return 0; + if (!edid) { + count = 0; + goto out; + } - if (off >= size) - return 0; + if (off >= size) { + count = 0; + goto out; + } if (off + count > size) count = size - off; memcpy(buf, edid + off, count); +out: + mutex_unlock(&drm_global_mutex); return count; } @@ -236,11 +260,12 @@ static ssize_t modes_show(struct device *device, struct drm_display_mode *mode; int written = 0; + mutex_lock(&drm_global_mutex); list_for_each_entry(mode, &connector->modes, head) { written += snprintf(buf + written, PAGE_SIZE - written, "%s\n", mode->name); } - + mutex_unlock(&drm_global_mutex); return written; } @@ -253,7 +278,9 @@ static ssize_t subconnector_show(struct device *device, struct drm_property *prop = NULL; uint64_t subconnector; int is_tv = 0; - int ret; + int ret = 0; + + mutex_lock(&drm_global_mutex); switch (connector->connector_type) { case DRM_MODE_CONNECTOR_DVII: @@ -268,21 +295,25 @@ static ssize_t subconnector_show(struct device *device, break; default: DRM_ERROR("Wrong connector type for this property\n"); - return 0; + goto out; } if (!prop) { DRM_ERROR("Unable to find subconnector property\n"); - return 0; + goto out; } ret = drm_connector_property_get_value(connector, prop, &subconnector); if (ret) - return 0; + goto out; - return snprintf(buf, PAGE_SIZE, "%s", is_tv ? - drm_get_tv_subconnector_name((int)subconnector) : - drm_get_dvi_i_subconnector_name((int)subconnector)); + ret = snprintf(buf, PAGE_SIZE, "%s", is_tv ? + drm_get_tv_subconnector_name((int)subconnector) : + drm_get_dvi_i_subconnector_name((int)subconnector)); + +out: + mutex_unlock(&drm_global_mutex); + return ret; } static ssize_t select_subconnector_show(struct device *device, -- 1.7.5.4 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel