Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

leds: trigger: netdev: Use mutex instead of spinlocks

Some LEDs may require to sleep while doing some operation like setting
brightness and other cleanup.

For this reason, using a spinlock will cause a sleep under spinlock
warning.

It should be safe to convert this to a sleepable lock since:
- sysfs read/write can sleep
- netdev_trig_work is a work queue and can sleep
- netdev _trig_notify can sleep

The spinlock was used when brightness didn't support sleeping, but this
changed and now it supported with brightness_set_blocking().

Convert to mutex lock to permit sleeping using brightness_set_blocking().

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://lore.kernel.org/r/20230419210743.3594-6-ansuelsmth@gmail.com

authored by

Christian Marangi and committed by
Lee Jones
d1b9e139 164b67d5

+9 -9
+9 -9
drivers/leds/trigger/ledtrig-netdev.c
··· 20 20 #include <linux/list.h> 21 21 #include <linux/module.h> 22 22 #include <linux/netdevice.h> 23 - #include <linux/spinlock.h> 23 + #include <linux/mutex.h> 24 24 #include <linux/timer.h> 25 25 #include "../leds.h" 26 26 ··· 37 37 */ 38 38 39 39 struct led_netdev_data { 40 - spinlock_t lock; 40 + struct mutex lock; 41 41 42 42 struct delayed_work work; 43 43 struct notifier_block notifier; ··· 97 97 struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev); 98 98 ssize_t len; 99 99 100 - spin_lock_bh(&trigger_data->lock); 100 + mutex_lock(&trigger_data->lock); 101 101 len = sprintf(buf, "%s\n", trigger_data->device_name); 102 - spin_unlock_bh(&trigger_data->lock); 102 + mutex_unlock(&trigger_data->lock); 103 103 104 104 return len; 105 105 } ··· 115 115 116 116 cancel_delayed_work_sync(&trigger_data->work); 117 117 118 - spin_lock_bh(&trigger_data->lock); 118 + mutex_lock(&trigger_data->lock); 119 119 120 120 if (trigger_data->net_dev) { 121 121 dev_put(trigger_data->net_dev); ··· 138 138 trigger_data->last_activity = 0; 139 139 140 140 set_baseline_state(trigger_data); 141 - spin_unlock_bh(&trigger_data->lock); 141 + mutex_unlock(&trigger_data->lock); 142 142 143 143 return size; 144 144 } ··· 279 279 280 280 cancel_delayed_work_sync(&trigger_data->work); 281 281 282 - spin_lock_bh(&trigger_data->lock); 282 + mutex_lock(&trigger_data->lock); 283 283 284 284 trigger_data->carrier_link_up = false; 285 285 switch (evt) { ··· 304 304 305 305 set_baseline_state(trigger_data); 306 306 307 - spin_unlock_bh(&trigger_data->lock); 307 + mutex_unlock(&trigger_data->lock); 308 308 309 309 return NOTIFY_DONE; 310 310 } ··· 365 365 if (!trigger_data) 366 366 return -ENOMEM; 367 367 368 - spin_lock_init(&trigger_data->lock); 368 + mutex_init(&trigger_data->lock); 369 369 370 370 trigger_data->notifier.notifier_call = netdev_trig_notify; 371 371 trigger_data->notifier.priority = 10;