Linux LED subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "A. Sverdlin" <alexander.sverdlin@siemens.com>,
	linux-leds@vger.kernel.org
Cc: lee@kernel.org
Subject: Re: [PATCH v5 4/4] leds: trigger: netdev: Serialize mode/interval stores with trigger lock
Date: Tue, 20 Oct 2026 12:59:07 +0000	[thread overview]
Message-ID: <sashiko-outbox-178980@kernel.org> (raw)
In-Reply-To: <20261020124651.1987272-5-alexander.sverdlin@siemens.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] leds: trigger: netdev: unlocked hw_control check in interval_store()
- [Medium] leds: trigger: netdev: missing carrier_link_up check in netdev_trig_sw_blink()
--

commit fa618832fa8e967d013f87c080cded7d0b155827
Author: Alexander Sverdlin <alexander.sverdlin@siemens.com>

leds: trigger: netdev: Serialize mode/interval stores with trigger lock

This commit serializes sysfs mode and interval attribute stores in the
netdev LED trigger using trigger_data->lock, switches to asynchronous
work cancellation to avoid deadlocking with netdev_trig_work(), and adds
a netdev_trig_sw_blink() helper to gate software activity polling.

> diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
> index bf9a5ec245a43..6859783422f5d 100644
> --- a/drivers/leds/trigger/ledtrig-netdev.c
> +++ b/drivers/leds/trigger/ledtrig-netdev.c
> @@ -81,6 +81,16 @@ struct led_netdev_data {
>  
>  static const struct attribute_group netdev_trig_link_speed_attrs_group;
>  
> +/* True while the software activity worker should keep polling and blinking. */
> +static bool netdev_trig_sw_blink(struct led_netdev_data *trigger_data)
> +{
> +	return trigger_data->net_dev && !trigger_data->hw_control &&
> +	       (test_bit(TRIGGER_NETDEV_TX, &trigger_data->mode) ||
> +		test_bit(TRIGGER_NETDEV_RX, &trigger_data->mode) ||
> +		test_bit(TRIGGER_NETDEV_TX_ERR, &trigger_data->mode) ||
> +		test_bit(TRIGGER_NETDEV_RX_ERR, &trigger_data->mode));
> +}

[Severity: Medium]
Should netdev_trig_sw_blink() also check trigger_data->carrier_link_up?

In set_baseline_state(), trigger_data->work is only scheduled when
trigger_data->carrier_link_up is true, and it is not cancelled when
carrier_link_up is false:

drivers/leds/trigger/ledtrig-netdev.c:set_baseline_state() {
	if (!trigger_data->carrier_link_up) {
		led_set_brightness(led_cdev, LED_OFF);
	} else {
		...
		if (netdev_trig_sw_blink(trigger_data))
			schedule_delayed_work(&trigger_data->work, 0);
	}
}

Both netdev_trig_notify() and set_device_name() call
cancel_delayed_work_sync(&trigger_data->work) before acquiring
trigger_data->lock:

drivers/leds/trigger/ledtrig-netdev.c:netdev_trig_notify() {
	cancel_delayed_work_sync(&trigger_data->work);

	mutex_lock(&trigger_data->lock);

	trigger_data->carrier_link_up = false;
	...
	set_baseline_state(trigger_data);

	mutex_unlock(&trigger_data->lock);
}

If a concurrent netdev_led_attr_store() or interval_store() acquires
trigger_data->lock in the window between cancel_delayed_work_sync() and
mutex_lock(&trigger_data->lock) while carrier_link_up is still true,
set_baseline_state() will re-arm trigger_data->work.

When netdev_trig_notify() or set_device_name() then acquires
trigger_data->lock, it sets carrier_link_up = false and sets the LED to
LED_OFF without cancelling the newly scheduled work. When netdev_trig_work()
runs, netdev_trig_sw_blink() returns true despite carrier_link_up being
false, allowing the worker to keep polling, blinking via
led_blink_set_oneshot(), and rescheduling itself while the link is down
(and leaving the LED on when any link or duplex mode bit sets invert = 1).

[ ... ]

> @@ -503,10 +520,14 @@ static ssize_t interval_store(struct device *dev,
>  
>  	/* impose some basic bounds on the timer interval */
>  	if (value >= 5 && value <= 10000) {
> -		cancel_delayed_work_sync(&trigger_data->work);
> +		mutex_lock(&trigger_data->lock);
> +
> +		cancel_delayed_work(&trigger_data->work);
>  
>  		atomic_set(&trigger_data->interval, msecs_to_jiffies(value));
>  		set_baseline_state(trigger_data);	/* resets timer */
> +
> +		mutex_unlock(&trigger_data->lock);
>  	}
>  
>  	return size;

[Severity: Medium]
Can interval_store() race with concurrent trigger_data->hw_control updates?

At the start of interval_store(), trigger_data->hw_control is checked
before acquiring trigger_data->lock:

drivers/leds/trigger/ledtrig-netdev.c:interval_store() {
	if (trigger_data->hw_control)
		return -EINVAL;
	...
	if (value >= 5 && value <= 10000) {
		mutex_lock(&trigger_data->lock);
}

If trigger_data->hw_control is false during that unlocked check, a
concurrent netdev_led_attr_store() or netdev_trig_notify() (on NETDEV_UP)
can acquire trigger_data->lock first, see the default interval in
can_hw_control(), and set trigger_data->hw_control = true.

When interval_store() then acquires trigger_data->lock, it does not
re-check trigger_data->hw_control before updating trigger_data->interval
and calling set_baseline_state(). Doesn't this allow trigger_data->interval
to be changed to a non-default value while hw_control is active, causing
subsequent can_hw_control() checks to unexpectedly drop out of hardware
offload?

[ ... ]

>
> base-commit: 3d229ce89862b8e82d71a9e11d6f840ca272a6d6

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261020124651.1987272-1-alexander.sverdlin@siemens.com?part=4

  reply	other threads:[~2026-10-20 12:59 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 12:46 [PATCH v5 0/4] leds: trigger: netdev: fix sysfs_update_group() races A. Sverdlin
2026-10-20 12:46 ` [PATCH v5 1/4] leds: trigger: netdev: Put netdev on activate error path A. Sverdlin
2026-10-20 12:51   ` sashiko-bot
2026-10-20 12:46 ` [PATCH v5 2/4] leds: trigger: netdev: Access net_dev under trigger_data->lock in the worker A. Sverdlin
2026-10-20 13:02   ` sashiko-bot
2026-10-20 12:46 ` [PATCH v5 3/4] leds: trigger: netdev: Fix sysfs_update_group() races A. Sverdlin
2026-10-20 12:56   ` sashiko-bot
2026-10-20 12:46 ` [PATCH v5 4/4] leds: trigger: netdev: Serialize mode/interval stores with trigger lock A. Sverdlin
2026-10-20 12:59   ` sashiko-bot [this message]
2026-10-20 14:40     ` Sverdlin, Alexander

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-178980@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=alexander.sverdlin@siemens.com \
    --cc=lee@kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox