lkml.org 
[lkml]   [2022]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [RFC PATCH v6 06/11] leds: trigger: netdev: add hardware control support
> +struct netdev_led_attr_detail {
> + char *name;
> + bool hardware_only;
> + enum led_trigger_netdev_modes bit;
> +};
> +
> +static struct netdev_led_attr_detail attr_details[] = {
> + { .name = "link", .bit = TRIGGER_NETDEV_LINK},
> + { .name = "tx", .bit = TRIGGER_NETDEV_TX},
> + { .name = "rx", .bit = TRIGGER_NETDEV_RX},

hardware_only is never set. Maybe it is used in a later patch? If so,
please introduce it there.

> static void set_baseline_state(struct led_netdev_data *trigger_data)
> {
> + int i;
> int current_brightness;
> + struct netdev_led_attr_detail *detail;
> struct led_classdev *led_cdev = trigger_data->led_cdev;

This file mostly keeps with reverse christmas tree, probably because
it was written by a netdev developer. It is probably not required for
the LED subsystem, but it would be nice to keep the file consistent.

> @@ -100,10 +195,15 @@ static ssize_t device_name_store(struct device *dev,
> size_t size)
> {
> struct led_netdev_data *trigger_data = led_trigger_get_drvdata(dev);
> + struct net_device *old_net = trigger_data->net_dev;
> + char old_device_name[IFNAMSIZ];
>
> if (size >= IFNAMSIZ)
> return -EINVAL;
>
> + /* Backup old device name */
> + memcpy(old_device_name, trigger_data->device_name, IFNAMSIZ);
> +
> cancel_delayed_work_sync(&trigger_data->work);
>
> spin_lock_bh(&trigger_data->lock);
> @@ -122,6 +222,19 @@ static ssize_t device_name_store(struct device *dev,
> trigger_data->net_dev =
> dev_get_by_name(&init_net, trigger_data->device_name);
>
> + if (!validate_baseline_state(trigger_data)) {

You probably want to validate trigger_data->net_dev is not NULL first. The current code
is a little odd with that,

> + /* Restore old net_dev and device_name */
> + if (trigger_data->net_dev)
> + dev_put(trigger_data->net_dev);
> +
> + dev_hold(old_net);

This dev_hold() looks wrong. It is trying to undo a dev_put()
somewhere? You should not actually do a put until you know you really
do not old_net, otherwise there is a danger it disappears and you
cannot undo.

> @@ -228,13 +349,22 @@ static ssize_t interval_store(struct device *dev,
> return ret;
>
> /* impose some basic bounds on the timer interval */
> - if (value >= 5 && value <= 10000) {
> - cancel_delayed_work_sync(&trigger_data->work);
> + if (value < 5 || value > 10000)
> + return -EINVAL;
> +
> + cancel_delayed_work_sync(&trigger_data->work);
> +
> + atomic_set(&trigger_data->interval, msecs_to_jiffies(value));
>
> - atomic_set(&trigger_data->interval, msecs_to_jiffies(value));
> - set_baseline_state(trigger_data); /* resets timer */
> + if (!validate_baseline_state(trigger_data)) {
> + /* Restore old interval on validation error */
> + atomic_set(&trigger_data->interval, old_interval);
> + trigger_data->mode = old_mode;

I think you need to schedule the work again, since you cancelled
it. It is at the end of the work that the next work is scheduled, and
so it will not self recover.

Andrew

\
 
 \ /
  Last update: 2022-05-05 03:01    [W:0.169 / U:0.468 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site