[PATCH v4 08/12] leds: trigger: Do not attach trigger to a removing LED

From: Rong Zhang

Date: Sat Aug 01 2026 - 13:30:31 EST


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 <i@xxxxxxxx>
---
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/20260719-leds-trigger-hw-changed-v3-0-5fb55722e36e@xxxxxxxx?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