* [RESEND PATCH 1/2] tty: serial: provide devm_uart_add_one_port()
2022-12-29 16:19 [RESEND PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port() Bartosz Golaszewski
@ 2022-12-29 16:19 ` Bartosz Golaszewski
2022-12-29 16:19 ` [RESEND PATCH 2/2] tty: serial: qcom-geni-serial: use devres for uart port management Bartosz Golaszewski
2023-01-19 14:10 ` [RESEND PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port() Greg Kroah-Hartman
2 siblings, 0 replies; 4+ messages in thread
From: Bartosz Golaszewski @ 2022-12-29 16:19 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
Jiri Slaby, Srinivas Kandagatla, Vinod Koul, Alex Elder
Cc: linux-kernel, linux-arm-msm, linux-serial, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Provide a devres variant of uart_add_one_port() that removes the managed
port at device detach.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
.../driver-api/driver-model/devres.rst | 3 ++
drivers/tty/serial/serial_core.c | 48 +++++++++++++++++++
include/linux/serial_core.h | 6 +++
3 files changed, 57 insertions(+)
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index 4249eb4239e0..1d79053070f5 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -448,6 +448,9 @@ RTC
SERDEV
devm_serdev_device_open()
+SERIAL
+ devm_uart_add_one_port()
+
SLAVE DMA ENGINE
devm_acpi_dma_controller_register()
devm_acpi_dma_controller_free()
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index b9fbbee598b8..996aa73705f8 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -3217,6 +3217,54 @@ int uart_remove_one_port(struct uart_driver *drv, struct uart_port *uport)
}
EXPORT_SYMBOL(uart_remove_one_port);
+struct uart_port_devres {
+ struct uart_driver *drv;
+ struct uart_port *port;
+};
+
+static void devm_uart_remove_one_port(struct device *dev, void *data)
+{
+ struct uart_port_devres *res = data;
+
+ uart_remove_one_port(res->drv, res->port);
+}
+
+/**
+ * devm_uart_add_one_port - managed variant of uart_register_driver()
+ * @dev: managed device
+ * @drv: pointer to the uart low level driver structure for this port
+ * @uport: uart port structure to use for this port.
+ *
+ * Context: task context, might sleep
+ *
+ * This is a devres wrapper around uart_add_one_port(). It allows the driver
+ * @drv to register its own uart_port structure with the core driver. The port
+ * will be unregistered on driver detach.
+ */
+int devm_uart_add_one_port(struct device *dev,
+ struct uart_driver *drv, struct uart_port *port)
+{
+ struct uart_port_devres *res;
+ int ret;
+
+ res = devres_alloc(devm_uart_remove_one_port, sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return -1;
+
+ ret = uart_add_one_port(drv, port);
+ if (ret) {
+ devres_free(res);
+ return -1;
+ }
+
+ res->drv = drv;
+ res->port = port;
+ devres_add(dev, res);
+
+ return 0;
+}
+EXPORT_SYMBOL(devm_uart_add_one_port);
+
/**
* uart_match_port - are the two ports equivalent?
* @port1: first port
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index fd59f600094a..3c86b751e3b6 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -857,6 +857,12 @@ int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
bool uart_match_port(const struct uart_port *port1,
const struct uart_port *port2);
+/*
+ * UART devres
+ */
+int devm_uart_add_one_port(struct device *dev,
+ struct uart_driver *drv, struct uart_port *port);
+
/*
* Power Management
*/
--
2.37.2
^ permalink raw reply related [flat|nested] 4+ messages in thread* [RESEND PATCH 2/2] tty: serial: qcom-geni-serial: use devres for uart port management
2022-12-29 16:19 [RESEND PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port() Bartosz Golaszewski
2022-12-29 16:19 ` [RESEND PATCH 1/2] tty: serial: provide devm_uart_add_one_port() Bartosz Golaszewski
@ 2022-12-29 16:19 ` Bartosz Golaszewski
2023-01-19 14:10 ` [RESEND PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port() Greg Kroah-Hartman
2 siblings, 0 replies; 4+ messages in thread
From: Bartosz Golaszewski @ 2022-12-29 16:19 UTC (permalink / raw)
To: Andy Gross, Bjorn Andersson, Konrad Dybcio, Greg Kroah-Hartman,
Jiri Slaby, Srinivas Kandagatla, Vinod Koul, Alex Elder
Cc: linux-kernel, linux-arm-msm, linux-serial, Bartosz Golaszewski
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Shrink and simplify the probe() and remove() code by using the managed
variant of uart_add_one_port().
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
---
drivers/tty/serial/qcom_geni_serial.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index b487823f0e61..7d5b51d7fb9e 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1470,7 +1470,7 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, port);
port->handle_rx = console ? handle_rx_console : handle_rx_uart;
- ret = uart_add_one_port(drv, uport);
+ ret = devm_uart_add_one_port(&pdev->dev, drv, uport);
if (ret)
return ret;
@@ -1479,7 +1479,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
IRQF_TRIGGER_HIGH, port->name, uport);
if (ret) {
dev_err(uport->dev, "Failed to get IRQ ret %d\n", ret);
- uart_remove_one_port(drv, uport);
return ret;
}
@@ -1496,7 +1495,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
port->wakeup_irq);
if (ret) {
device_init_wakeup(&pdev->dev, false);
- uart_remove_one_port(drv, uport);
return ret;
}
}
@@ -1506,12 +1504,8 @@ static int qcom_geni_serial_probe(struct platform_device *pdev)
static int qcom_geni_serial_remove(struct platform_device *pdev)
{
- struct qcom_geni_serial_port *port = platform_get_drvdata(pdev);
- struct uart_driver *drv = port->private_data.drv;
-
dev_pm_clear_wake_irq(&pdev->dev);
device_init_wakeup(&pdev->dev, false);
- uart_remove_one_port(drv, &port->uport);
return 0;
}
--
2.37.2
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [RESEND PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port()
2022-12-29 16:19 [RESEND PATCH 0/2] tty: serial: add and use a managed variant of uart_add_one_port() Bartosz Golaszewski
2022-12-29 16:19 ` [RESEND PATCH 1/2] tty: serial: provide devm_uart_add_one_port() Bartosz Golaszewski
2022-12-29 16:19 ` [RESEND PATCH 2/2] tty: serial: qcom-geni-serial: use devres for uart port management Bartosz Golaszewski
@ 2023-01-19 14:10 ` Greg Kroah-Hartman
2 siblings, 0 replies; 4+ messages in thread
From: Greg Kroah-Hartman @ 2023-01-19 14:10 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Andy Gross, Bjorn Andersson, Konrad Dybcio, Jiri Slaby,
Srinivas Kandagatla, Vinod Koul, Alex Elder, linux-kernel,
linux-arm-msm, linux-serial, Bartosz Golaszewski
On Thu, Dec 29, 2022 at 05:19:46PM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> Resending rebased on top of v6.2-rc1
>
> --
>
> This series adds a managed variant of uart_add_one_port() and uses it in the
> qcom-geni-serial driver.
>
> I've been asked by Greg to send it separately and he didn't seem to be
> impressed by the proposition of adding devres interfaces to the tty layer
> in general. I can only assume it has something to do with the ongoing
> discussion about the supposed danger of using devres interfaces in conjunction
> with exporting character devices to user-space.
That is correct.
> The bug in question can be triggered by opening a device file, unbinding the
> driver that exported it and then calling any of the system calls on the
> associated file descriptor.
>
> After some testing I noticed that many subsystems are indeed either crashing
> or deadlocking in the above situation. I've sent patches that attempt to fix
> the GPIO and I2C subsystems[1][2]. Neither of these issues have anything to
> do with devres and all to do with the fact that certain resources are freed
> on driver unbind and others need to live for as long as the character device
> exists. More details on that in the cover letters and commit messages in the
> links.
>
> I'd like to point out that the serial code is immune to this issue as before
> every operation, the serial core takes the port lock and checks the uart
> state. If the device no longer exists (when the uart port is removed, the
> pointer to uart_port inside uart_state is to NULL), it gracefully returns
> -ENODEV to user-space.
>
> Please consider applying the patches in the series as devres is the easiest
> way to lessen the burden on driver developers when dealing with complex error
> paths and resource leaks. The general rule for devres is: if it can be freed
> in .remove() then it can be managed by devres, which is the case for this new
> helper.
Overall you are adding more code to the kernel than removing, so how is
this a win? Perhaps if other drivers were converted over to this new
function then I would be more inclined to be able to accept it.
But as-is, with only one user, it's a non-starter, sorry.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 4+ messages in thread