Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752320AbcKGJLU (ORCPT ); Mon, 7 Nov 2016 04:11:20 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:12207 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750927AbcKGJLQ (ORCPT ); Mon, 7 Nov 2016 04:11:16 -0500 X-AuditID: cbfec7f5-f79ce6d000004c54-d7-5820453003ce Subject: Re: [PATCH] leds: Add mutex protection in brightness_show() To: Hans de Goede , linux-leds@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Sakari Ailus , Pavel Machek , Andrew Lunn From: Jacek Anaszewski Message-id: <32b106fa-1315-3e27-07b6-1f91ac9773c4@samsung.com> Date: Mon, 07 Nov 2016 10:11:10 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-version: 1.0 In-reply-to: <1189fd14-a0a6-867e-1082-e84771f29014@redhat.com> Content-type: text/plain; charset=windows-1252; format=flowed Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuphleLIzCtJLcpLzFFi42LZduzneV0DV4UIg2mvRCzO3z3EbPHm+HQm i8u75rBZbH2zjtHi7qmjbBaftnxjcmDzmHcy0GPnjs9MHu/3XWXzWLH6O7vH501yAaxRXDYp qTmZZalF+nYJXBnzp7ayFJxVrvi3sou9gXGRbBcjJ4eEgInE7xnH2CBsMYkL99YD2VwcQgJL GSXOPu1khHA+M0rMndTLBNNx4dZKqKpljBKXVl9hhXCeMUqsbXrMClIlLOAiMXXeE0YQW0TA WaKrcwMTSBGzQA+jxK3n01hAEmwChhI/X7wGSnBw8ArYSTQtFwcJswioSnzf2cwOEhYViJDY fTcVJMwrICjxY/I9sE5OoOpZzz4xg9jMAo4SDxbtZIWw5SU2r3nLDLJKQmAeu8TEd6fZQOZI CMhKbDrADPGAi8Szd++gbGGJV8e3sEPYMhKdHQeZIHonM0pcPHaTFcJZzSixsbOTBaLKWqLh /y8WiG18EpO2TWeGWMAr0dEmBFHiITF1w09omDpKvL/2Bxpab5kk9k65yTSBUX4WkodmIXli FpInFjAyr2IUSS0tzk1PLTbVK07MLS7NS9dLzs/dxAhMI6f/Hf+6g3HpMatDjAIcjEo8vAI2 8hFCrIllxZW5hxglOJiVRHjf2ytECPGmJFZWpRblxxeV5qQWH2KU5mBREufds+BKuJBAemJJ anZqakFqEUyWiYNTqoHRP8Xjhp6rlpB8VsJF09dmd2ZX/WI1Kxa8x6KQ5Nq4UMLanufAi0/n n176XSty9/JdLY8pkl1f1AML6nd9fpj/m6fZ1dpqreymFoHjx4zrX7Qv3L7n9EP+h53LnBcH 118SrD4Z82XDyWnqQYZRGon5fx12Kc5RWX5l9l6+7w81X4kuZRPz6dmtxFKckWioxVxUnAgA kHwamh8DAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrNIsWRmVeSWpSXmKPExsVy+t/xy7p6rgoRBpv+clqcv3uI2eLN8elM Fpd3zWGz2PpmHaPF3VNH2Sw+bfnG5MDmMe9koMfOHZ+ZPN7vu8rmsWL1d3aPz5vkAlij3Gwy UhNTUosUUvOS81My89JtlUJD3HQtlBTyEnNTbZUidH1DgpQUyhJzSoE8IwM04OAc4B6spG+X 4JYxf2orS8FZ5Yp/K7vYGxgXyXYxcnJICJhIXLi1kg3CFpO4cG89mC0ksIRR4v+W9C5GLiD7 GaPE+8nvWEASwgIuElPnPWEEsUUEnCW6OjcwQRS9ZZJYsb6bDcRhFuhilFh+cypYFZuAocTP F6+Bqjg4eAXsJJqWi4OEWQRUJb7vbGYHsUUFIiRurfoIVs4rICjxY/I9sGWcQOWznn1iBrGZ BWwlFrxfxwJhy0tsXvOWeQKjwCwkLbOQlM1CUraAkXkVo0hqaXFuem6xoV5xYm5xaV66XnJ+ 7iZGYERtO/Zz8w7GSxuDDzEKcDAq8fAK2MhHCLEmlhVX5h5ilOBgVhLhfW+vECHEm5JYWZVa lB9fVJqTWnyI0RToiYnMUqLJ+cBozyuJNzQxNLc0NDK2sDA3MlIS5y35cCVcSCA9sSQ1OzW1 ILUIpo+Jg1OqgTFWzD4o6YjI8jk/nTy9087GBf3LD5KVPG59YIb7qQnfox30DL41HWhc+Vwo 4Uflp3/pFa32ug97/I/vn/02dt+mUHH+eUb3p94/Uh+nsI7H2PdH8otWad8n6dzfH3HvFOeU Ko5VPxq581ub2QU1lr+3bc0de1ynbmYOqLjiZzlzp4iwrD7XRyWW4oxEQy3mouJEABZ3qlm+ AgAA X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20161107091111eucas1p233b9ade40b0eaff0360b0584171a74cf X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 X-Local-Sender: =?UTF-8?B?SmFjZWsgQW5hc3pld3NraRtTUlBPTC1TeXN0ZW0gRlcgIChN?= =?UTF-8?B?Qikb7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?SmFjZWsgQW5hc3pld3NraRtTUlBPTC1TeXN0ZW0gRlcgIChN?= =?UTF-8?B?QikbU2Ftc3VuZyBFbGVjdHJvbmljcxtTZW5pb3IgU29mdHdhcmUgRW5naW5l?= =?UTF-8?B?ZXI=?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjc1MjY=?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20161104115324epcas3p32bee0b0f57ae8d1141ded4fa1d1f2ae2 X-RootMTR: 20161104115324epcas3p32bee0b0f57ae8d1141ded4fa1d1f2ae2 References: <1478245962-15706-1-git-send-email-j.anaszewski@samsung.com> <9d28f3d3-1d3d-c670-a102-3e2698764fdd@samsung.com> <9367cc2f-5ce9-0443-bb87-66198d437061@redhat.com> <1189fd14-a0a6-867e-1082-e84771f29014@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4452 Lines: 105 Hi, On 11/06/2016 03:52 PM, Hans de Goede wrote: > Hi, > > On 04-11-16 17:46, Hans de Goede wrote: >> Hi, >> >> On 04-11-16 17:06, Jacek Anaszewski wrote: >>> Hi Hans, >>> >>> On 11/04/2016 12:53 PM, Hans de Goede wrote: >>>> Hi, >>>> >>>> On 04-11-16 08:52, Jacek Anaszewski wrote: >>>>> 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(), >>>>> resulting in overwriting new brightness with the old one before >>>>> the former is written to the device. >>>>> >>>>> Signed-off-by: Jacek Anaszewski >>>>> Cc: Hans de Goede >>>>> Cc: Sakari Ailus >>>>> Cc: Pavel Machek >>>>> Cc: Andrew Lunn >>>>> --- >>>>> drivers/leds/led-class.c | 3 ++- >>>>> 1 file changed, 2 insertions(+), 1 deletion(-) >>>>> >>>>> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c >>>>> index 731e4eb..0c2307b 100644 >>>>> --- a/drivers/leds/led-class.c >>>>> +++ b/drivers/leds/led-class.c >>>>> @@ -30,8 +30,9 @@ static ssize_t brightness_show(struct device *dev, >>>>> { >>>>> struct led_classdev *led_cdev = dev_get_drvdata(dev); >>>>> >>>>> - /* no lock needed for this */ >>>>> + mutex_lock(&led_cdev->led_access); >>>>> led_update_brightness(led_cdev); >>>>> + mutex_unlock(&led_cdev->led_access); >>>>> >>>>> return sprintf(buf, "%u\n", led_cdev->brightness); >>>>> } >>>>> >>>> >>>> I'm afraid that this fix is not enough, the led_access lock is only >>>> held when the brightness is being updated through sysfs, not for >>>> trigger / sw-blinking updates (which cannot take a mutex as they >>>> may be called from non blocking contexts). >>>> >>>> We may need to consider to add a spinlock to the led_classdev and >>>> always lock that when calling into the driver, except for when >>>> the driver has a brightness_set_blocking callback. Which will need >>>> special handling. >>> >>> led_update_brightness() currently has two users besides LED subsystem >>> (at least grep reports those places): >>> >>> 1. v4l2-flash-led-class wrapper, for which led_access mutex was >>> introduced. Its purpose was to disable LED sysfs interface while >>> v4l2-flash wrapper takes over control of LED class device >>> (not saying that the mutex wasn't missing even without this >>> use case). Now I've realized that the call to >>> led_sysfs_is_disabled() is missing in this patch. >>> 2. /drivers/platform/x86/thinkpad_acpi.c - it calls >>> led_update_brightness() on suspend >>> >>> I think that the best we can now do is to add >>> lockdep_assert_held(&led_cdev->led_access) in led_update_brightness() >>> and a description saying that the caller has to acquire led_access >>> lock before calling it. Similarly as in case of >>> led_sysfs_disable()/led_sysfs_disable(). >> >> The problem is not only callers of led_update_brightness() not holding >> led_cdev->led_access, the problem is also callers of led_set_brightness >> not holding led_cdev->led_access and they cannot take this lock because >> they may be called from a non-blocking context. > > Thinking more about this, using a spinlock is also not going to work > because led_cdev->brightness_set_blocking and led_cdev->brightness_get > can both block and thus cannot be called with a spinlock held. > > I think that we need to just make this a problem of the led drivers > and in include/linux/leds.h document that the led-core does not do > locking and that the drivers themselves need to protect against > their brightness_set / brightness_get callbacks when necessary. Thanks for the analysis. Either way, this patch, with the modification I mentioned in my previous message is required to assure proper LED sysfs locking. Regarding the races between user and atomic context, I think that it should be system root's responsibility to define LED access policy. If a LED is registered for any trigger events then setting brightness from user space should be made impossible. Such a hint could be even added to the Documentation/leds/leds-class.txt. -- Best regards, Jacek Anaszewski