[PATCH v4 08/12] leds: trigger: Do not attach trigger to a removing LED
Rong Zhang <[email protected]> Sun, 02 Aug 2026 01:26:52 +0800
| Newsgroups | org.kernel.vger.platform-driver-x86,dev.linux.lists.chrome-platform,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-leds,org.kernel.vger.netdev |
|---|---|
| Message-ID | <[email protected]> |
Currently the LED trigger core knows little about an LED's removal as the LED_UNREGISTERING flag is set too late. This could lead to a race condition where a trigger may be attached to a removing LED right after its previous trigger is removed. Set the flag at the very beginning of led_classdev_unregister(), and check the flag before attaching a trigger. Signed-off-by: Rong Zhang <[email protected]> --- Changes in v4: - New patch in the series to address concerns from Sashiko - Without it, following patches will expose a race condition - https://sashiko.dev/#/patchset/[email protected]?part=8 --- drivers/leds/led-class.c | 4 ++-- drivers/leds/led-triggers.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 2460fcf0c469..4158337896bc 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -631,6 +631,8 @@ void led_classdev_unregister(struct led_classdev *led_cdev) if (IS_ERR_OR_NULL(led_cdev->dev)) return; + led_cdev->flags |= LED_UNREGISTERING; + #ifdef CONFIG_LEDS_TRIGGERS down_write(&led_cdev->trigger_lock); if (led_cdev->trigger) @@ -638,8 +640,6 @@ void led_classdev_unregister(struct led_classdev *led_cdev) up_write(&led_cdev->trigger_lock); #endif - led_cdev->flags |= LED_UNREGISTERING; - /* Stop blinking */ led_stop_software_blink(led_cdev); diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index cb49a02a8b3c..64bc95d0bfeb 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -200,6 +200,9 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) const char *name; int ret; + if ((led_cdev->flags & LED_UNREGISTERING) && trig) + return -ENODEV; + if (!led_cdev->trigger && !trig) return 0; -- 2.53.0