* [PATCH v2] leds: trigger: Call synchronize_rcu() before calling trig->activate()
@ 2024-05-31 12:01 Hans de Goede
2024-05-31 12:38 ` (subset) " Lee Jones
0 siblings, 1 reply; 2+ messages in thread
From: Hans de Goede @ 2024-05-31 12:01 UTC (permalink / raw)
To: Pavel Machek, Lee Jones; +Cc: Hans de Goede, Kate Hsuan, linux-leds
Some triggers call led_trigger_event() from their activate() callback
to initialize the brightness of the LED for which the trigger is being
activated.
In order for the LED's initial state to be set correctly this requires that
the led_trigger_event() call uses the new version of trigger->led_cdevs,
which has the new LED.
AFAICT led_trigger_event() will always use the new version when it is
running on the same CPU as where the list_add_tail_rcu() call was made,
which is why the missing synchronize_rcu() has not lead to bug reports.
But if activate() is pre-empted, sleeps or uses a worker then
the led_trigger_event() call may run on another CPU which may still use
the old trigger->led_cdevs list.
Add a synchronize_rcu() call to ensure that any led_trigger_event() calls
done from activate() always use the new list.
Triggers using led_trigger_event() from their activate() callback are:
net/bluetooth/leds.c, net/rfkill/core.c and drivers/tty/vt/keyboard.c.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v2:
- Rebase on top of v6.10-rc1
---
drivers/leds/led-triggers.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index b1b323b19301..07ce5cf76cf4 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -194,6 +194,13 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
spin_unlock(&trig->leddev_list_lock);
led_cdev->trigger = trig;
+ /*
+ * Some activate() calls use led_trigger_event() to initialize
+ * the brightness of the LED for which the trigger is being set.
+ * Ensure the led_cdev is visible on trig->led_cdevs for this.
+ */
+ synchronize_rcu();
+
ret = 0;
if (trig->activate)
ret = trig->activate(led_cdev);
--
2.45.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: (subset) [PATCH v2] leds: trigger: Call synchronize_rcu() before calling trig->activate()
2024-05-31 12:01 [PATCH v2] leds: trigger: Call synchronize_rcu() before calling trig->activate() Hans de Goede
@ 2024-05-31 12:38 ` Lee Jones
0 siblings, 0 replies; 2+ messages in thread
From: Lee Jones @ 2024-05-31 12:38 UTC (permalink / raw)
To: Pavel Machek, Lee Jones, Hans de Goede; +Cc: Kate Hsuan, linux-leds
On Fri, 31 May 2024 14:01:24 +0200, Hans de Goede wrote:
> Some triggers call led_trigger_event() from their activate() callback
> to initialize the brightness of the LED for which the trigger is being
> activated.
>
> In order for the LED's initial state to be set correctly this requires that
> the led_trigger_event() call uses the new version of trigger->led_cdevs,
> which has the new LED.
>
> [...]
Applied, thanks!
[1/1] leds: trigger: Call synchronize_rcu() before calling trig->activate()
commit: 47b8a4059f8a8b2407ab22fad8775842c54e59c6
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-05-31 12:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-31 12:01 [PATCH v2] leds: trigger: Call synchronize_rcu() before calling trig->activate() Hans de Goede
2024-05-31 12:38 ` (subset) " Lee Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).