Re: Bug when using both "set" and "blink" functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/22/2017 01:55 AM, Craig McQueen wrote:
> I'd like to control a LED to possibly be any of:
> 
> * Off
> * On
> * Blinking
> 
> I've had this working fine in 3.14.x kernel.
> 
> But when upgrading to 4.4.x, I found that the transition from "blinking" to "on" didn't work. Namely, if it's blinking and then I call led_set_brightness(led_cdev, LED_FULL), then it wouldn't work (I can't remember if it turned off, or remained blinking; it wasn't on anyway). I worked around it by calling led_set_brightness(led_cdev, LED_OFF) just before led_set_brightness(led_cdev, LED_FULL).

Could you please check it with 4.14?

The expected behavior in 4.14 is:

use case 1: led_set_brightness(led_cdev, LED_OFF) while timer trigger
            is active.
expected result: LED is off, trigger is deactivated.

use case 2: led_set_brightness(led_cdev, LED_FULL) while timer trigger
            is active.
expected result: LED blink brightness is LED_FULL, trigger remains active.

> Now I have upgraded to 4.9.x, and found that the transition from "blinking" to "on" again isn't working. The LED ends up being off instead of on.

Could you provide the exact steps to reproduce this case?
LED shouldn't be in any way off after setting brightness to non-zero
value when blinking.

There were indeed changes in 4.9 in this area, that modified semantics
of setting brightness to non-zero value when blinking. See the
reasoning:

commit 7cfe749fad5158247282f2fee30773fd454029ab
Author: Tony Makkiel <tony.makkiel@xxxxxxxxx>
Date:   Wed May 18 17:22:45 2016 +0100

    leds: core: Fix brightness setting upon hardware blinking enabled

    Commit 76931edd54f8 ("leds: fix brightness changing when software
blinking
    is active") changed the semantics of led_set_brightness() which
according
    to the documentation should disable blinking upon any brightness
setting.
    Moreover it made it different for soft blink case, where it was possible
    to change blink brightness, and for hardware blink case, where setting
    any brightness greater than 0 was ignored.

    While the change itself is against the documentation claims, it was
driven
    also by the fact that timer trigger remained active after turning
blinking
    off. Fixing that would have required major refactoring in the led-core,
    led-class, and led-triggers because of cyclic dependencies.

    Finally, it has been decided that allowing for brightness change during
    blinking is beneficial as it can be accomplished without disturbing
    blink rhythm.

    The change in brightness setting semantics will not affect existing
    LED class drivers that implement blink_set op thanks to the LED_BLINK_SW
    flag introduced by this patch. The flag state will be from now on
checked
    in led_set_brightness() which will allow to distinguish between software
    and hardware blink mode. In the latter case the control will be passed
    directly to the drivers which apply their semantics on brightness set,
    which is disable the blinking in case of most such drivers. New drivers
    will apply new semantics and just change the brightness while hardware
    blinking is on, if possible.

    The issue was smuggled by subsequent LED core improvements, which
modified
    the code that originally introduced the problem.



> Examining the code of led_set_brightness():
> 
> * Behaviour is different depending on whether the brightness is LED_OFF (it schedules the blink to be turned off "soon") or other (it alters the brightness of subsequent blinks).
> * It looks as though there are race conditions in the transition from blinking to steady off -- it schedules the blink to be turned off "soon", so it's difficult to guarantee a reliable transition from blinking to on/off.
> 
> The combination of the above two points makes it seem difficult to robustly go from blinking to off/on.
> 
> So, my questions are:
> 
> * What is the correct way to use the API to reliably control an LED for a combination of off/on/blinking?
> * Is my above analysis of the code correct, so that there are indeed race conditions going from blinking to off, leading to undefined behaviour? Can that be fixed?

I checked earlier discussed case i.e. disabling trigger and immediately
setting brightness to non-zero value and it seems to work fine. Checked
with uleds driver:

# echo "timer" > trigger
# echo 0 > brightness; echo 100 > brightness

Brightness always is 100 after that, even when setting
delay_on/off to 1.

-- 
Best regards,
Jacek Anaszewski



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux