Thread (14 messages) flat view 14 messages, 2 authors, 2026-08-19
COLD33d

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

From: Rong Zhang <hidden>
Date: 2026-08-01 17:30:19
Also in: chrome-platform, linux-leds, lkml, netdev, platform-driver-x86
Subsystem: led subsystem, the rest · Maintainers: Lee Jones, Pavel Machek, Linus Torvalds

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 <redacted>
---
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@rong.moe?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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help