Initially the claim about no need for lock in brightness_show() was valid as the function was just returning unchanged LED brightness. After the addition of led_update_brightness() this is no longer true, as the function can change the brightness if a LED class driver implements brightness_get op. It can lead to races between led_update_brightness() and led_set_brightness(). Signed-off-by: Jacek Anaszewski <j.anaszewski@xxxxxxxxxxx> Cc: Hans de Goede <hdegoede@xxxxxxxxxx> Cc: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> Cc: Pavel Machek <pavel@xxxxxx> Cc: Andrew Lunn <andrew@xxxxxxx> --- Changes since v1: - added led_sysfs_is_disabled() check - moved sprintf under mutex protection drivers/leds/led-class.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index b12f861..e472407 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -29,11 +29,23 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *attr, char *buf) { struct led_classdev *led_cdev = dev_get_drvdata(dev); + int ret; - /* no lock needed for this */ - led_update_brightness(led_cdev); + mutex_lock(&led_cdev->led_access); + + if (led_sysfs_is_disabled(led_cdev)) { + ret = -EBUSY; + goto unlock; + } + + ret = led_update_brightness(led_cdev); + if (ret < 0) + goto unlock; - return sprintf(buf, "%u\n", led_cdev->brightness); + ret = sprintf(buf, "%u\n", led_cdev->brightness); +unlock: + mutex_unlock(&led_cdev->led_access); + return ret; } static ssize_t brightness_store(struct device *dev, -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-leds" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html