Hi Pavel, On Thu, Feb 18, 2021 at 02:37:33PM +0100, Pavel Machek wrote: > Close, but see below: > > > +static ssize_t ttyname_store(struct device *dev, > > + struct device_attribute *attr, const char *buf, > > + size_t size) > > +{ > > + struct ledtrig_tty_data *trigger_data = led_trigger_get_drvdata(dev); > > + char *ttyname; > > + ssize_t ret = size; > > + bool running; > > + > > + if (size > 0 && buf[size - 1] == '\n') > > + size -= 1; > > + > > + if (size) { > > + ttyname = kmemdup_nul(buf, size, GFP_KERNEL); > > + if (!ttyname) { > > + ret = -ENOMEM; > > + goto out_unlock; > > Unlock without a lock: > > > +out_unlock: > > + mutex_unlock(&trigger_data->mutex); Indeed, I prepare an incremental patch that does return -ENOMEM instead of goto out_unlock. > > + > > + if (ttyname && !running) > > + ledtrig_tty_restart(trigger_data); > > + > > + return ret; > > +} > > > + > > + tty = tty_kopen_shared(devno); > > + if (IS_ERR(tty) || !tty) > > + /* What to do? retry or abort */ > > + goto out; > > Abort would make sense to me. In this case it would IMHO be sensible to already try the tty_kopen_shared() in ttyname_store() and let that one fail if the tty doesn't exist. I'll have to go through the history of this patch set, if I remember correctly it was like that at one point. > > + if (icount.rx != trigger_data->rx || > > + icount.tx != trigger_data->tx) { > > + led_set_brightness(trigger_data->led_cdev, LED_ON); > > Please use _sync version. OK, there are too many variants for me. I'll just believe you that led_set_brightness_sync is the right one. (Hmm, on the other hand I'll have to understand the difference for a good commit log. I'll dig into that. "Pavel said so" probably isn't good enough :-)) Best regards and thanks for your review, Uwe -- Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |