serdev: fix broken lifetime assumptions
Subsystems (2)
v2 cover serdev: fix broken lifetime assumptions
This series fixes a number of issues with the new serdev code, which was based on incorrect tty-port lifetime assumptions.
The first patch in v1 of this series disables serdev support by reverting the patch which hooked into the tty layer in a broken way that leads to crashes and leaks when deregistering devices. That one has now been applied to tty-linus with a stable tag (for v4.11).
The remaining two patches again re-enables serdev (first enabled in 4.11, but soon reverted in stable) for a subset of tty drivers by adding adding a new interface for registering serdev devices and using that in serial core only.
More details can be found in the individual commit messages.
Johan
Changes in v2
- rebase on tty-linus
- drop first two patches that have already been applied
- remove a stray newline in patch 1/2
- add Rob's reviewed-by tag
Johan Hovold (2):
tty/serdev: add serdev registration interface
serial: enable serdev support
drivers/tty/serdev/serdev-ttyport.c | 6 ++- drivers/tty/serial/serial_core.c | 4 +- drivers/tty/tty_port.c | 75 +++++++++++++++++++++++++++++++++++++ include/linux/serdev.h | 7 +++- include/linux/tty.h | 9 +++++ 5 files changed, 95 insertions(+), 6 deletions(-)
Signature · 1 line
2.13.0
PATCH v2 1/2 tty/serdev: add serdev registration interface
Add a new interface for registering a serdev controller and clients, and a helper function to deregister serdev devices (or a tty device) that were previously registered using the new interface.
Once every driver currently using the tty_port_register_device() helpers have been vetted and converted to use the new serdev registration interface (at least for deregistration), we can move serdev registration to the current helpers and get rid of the serdev-specific functions.
--- drivers/tty/serdev/serdev-ttyport.c | 6 ++- drivers/tty/tty_port.c | 75 +++++++++++++++++++++++++++++++++++++ include/linux/serdev.h | 7 +++- include/linux/tty.h | 9 +++++ 4 files changed, 93 insertions(+), 4 deletions(-)
drivers/tty/serdev/serdev-ttyport.c +4 -2
@@ -250,16 +250,18 @@ struct device *serdev_tty_port_register(struct tty_port *port,return ERR_PTR (ret); } -void serdev_tty_port_unregister (struct tty_port *port) +int serdev_tty_port_unregister (struct tty_port *port) {struct serdev_controller *ctrl = port->client_data;struct serport *serport =serdev_controller_get_drvdata (ctrl);if (!serport) -return ; +return -ENODEV ;serdev_controller_remove (ctrl); port->client_ops =NULL ; port->client_data =NULL ;serdev_controller_put (ctrl); + +return 0 ; }
drivers/tty/tty_port.c +75 -0
87 lines not on this page · raw message
include/linux/serdev.h +5 -2
@@ -308,7 +308,7 @@ struct tty_driver;struct device *serdev_tty_port_register (struct tty_port *port,struct device *parent,struct tty_driver *drv,int idx); -void serdev_tty_port_unregister (struct tty_port *port); +int serdev_tty_port_unregister (struct tty_port *port);#else static inline struct device *serdev_tty_port_register(struct tty_port *port, struct device *parent,
@@ -316,7 +316,10 @@ static inline struct device *serdev_tty_port_register(struct tty_port *port, {return ERR_PTR (-ENODEV ); } -static inline void serdev_tty_port_unregister (struct tty_port *port) {} +static inline int serdev_tty_port_unregister (struct tty_port *port) +{ +return -ENODEV ; +}#endif /* CONFIG_SERIAL_DEV_CTRL_TTYPORT */ #endif /*_LINUX_SERDEV_H */
include/linux/tty.h +9 -0
@@ -558,6 +558,15 @@ extern struct device *tty_port_register_device_attr(struct tty_port *port, struct tty_driver *driver, unsigned index, struct device *device, void *drvdata, const struct attribute_group **attr_grp); +extern struct device *tty_port_register_device_serdev (struct tty_port *port, +struct tty_driver *driver,unsigned index, +struct device *device); +extern struct device *tty_port_register_device_attr_serdev (struct tty_port *port, +struct tty_driver *driver,unsigned index, +struct device *device,void *drvdata, +const struct attribute_group **attr_grp); +extern void tty_port_unregister_device (struct tty_port *port, +struct tty_driver *driver,unsigned index);extern int tty_port_alloc_xmit_buf (struct tty_port *port);extern void tty_port_free_xmit_buf (struct tty_port *port);extern void tty_port_destroy (struct tty_port *port);
Signature · 1 line
2.13.0
PATCH v2 2/2 serial: enable serdev support
In reply to Johan HovoldEnable serdev support by using the new device-registration helpers.
--- drivers/tty/serial/serial_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/tty/serial/serial_core.c +2 -2
@@ -2782,7 +2782,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)* Register the port whether it's detected or not. This allows * setserial to be used to alter this port's parameters. */ - tty_dev =tty_port_register_device_attr (port, drv->tty_driver, + tty_dev =tty_port_register_device_attr_serdev (port, drv->tty_driver, uport->line, uport->dev, port, uport->tty_groups);if (likely (!IS_ERR (tty_dev))) {device_set_wakeup_capable (tty_dev,1 );
@@ -2845,7 +2845,7 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)/* * Remove the devices from the tty layer */ -tty_unregister_device (drv->tty_driver, uport->line); +tty_port_unregister_device (port, drv->tty_driver, uport->line); tty =tty_port_tty_get (port);if (tty) {
Signature · 1 line
2.13.0