From: James Hilliard <james.hilliard1@gmail.com>
To: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Jiri Slaby" <jirislaby@kernel.org>,
"Raul E Rangel" <rrangel@chromium.org>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
"Heikki Krogerus" <heikki.krogerus@linux.intel.com>,
"Tony Lindgren" <tony@atomide.com>,
"Sebastian Andrzej Siewior" <bigeasy@linutronix.de>,
"Richard Genoud" <richard.genoud@bootlin.com>,
"Nicolas Ferre" <nicolas.ferre@microchip.com>,
"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Claudiu Beznea" <claudiu.beznea@tuxon.dev>,
"Jacky Huang" <ychuang3@nuvoton.com>,
"Shan-Chun Hung" <schung@nuvoton.com>,
"Pali Rohár" <pali@kernel.org>, "Frank Li" <Frank.Li@nxp.com>,
"Sascha Hauer" <s.hauer@pengutronix.de>,
"Pengutronix Kernel Team" <kernel@pengutronix.de>,
"Fabio Estevam" <festevam@gmail.com>,
"Maciej W. Rozycki" <macro@orcam.me.uk>,
"Timur Tabi" <timur@kernel.org>,
"Peter Ujfalusi" <peter.ujfalusi@ti.com>,
"Vignesh Raghavendra" <vigneshr@ti.com>,
"Patrice Chotard" <patrice.chotard@foss.st.com>
Cc: linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev,
linuxppc-dev@lists.ozlabs.org,
James Hilliard <james.hilliard1@gmail.com>
Subject: [PATCH v9 8/8] serial: 8250: retain DMA resources when termination fails
Date: Mon, 02 Nov 2026 16:14:35 -0700 [thread overview]
Message-ID: <20261102-submit-serial-8250-dma-cancel-v1-v9-8-9159caade148@gmail.com> (raw)
In-Reply-To: <20261102-submit-serial-8250-dma-cancel-v1-v9-0-9159caade148@gmail.com>
serial8250_release_dma() ignores the return from dmaengine_terminate_sync()
before freeing the coherent RX buffer, unmapping the TX FIFO and releasing
the channels. If the provider fails to stop a channel, the DMAengine
wrapper returns the error without synchronizing its callbacks. Hardware
or a detached callback can then access the released storage and state.
Checking the error and returning early would not preserve their lifetime:
serial core frees the TX FIFO after the driver's shutdown callback returns,
and port removal can then release the callback context as well.
Require successful synchronous termination of both channels before
releasing any DMA resources. Retry failed channels after a sleep outside
the port lock, leaving channels that have already stopped and drained
alone. Keep the shutdown gate and storage reservation in place throughout
the retries.
Start retries with a 1 ms sleep and double it up to one second. This
makes short-lived failures responsive while bounding sustained retry
activity; neither delay is a hardware timeout. Report the initial failure,
rate-limit ongoing failures with the elapsed time and current RX/TX error
codes, and report recovery once both channels have stopped and drained.
A permanently failed DMA engine blocks close or removal. This deliberately
retains the buffers, mappings, channels and callback context until the
provider can establish that they are no longer in use.
Fixes: 9ee4b83e51f7 ("serial: 8250: Add support for dmaengine")
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/tty/serial/8250/8250_dma.c | 43 ++++++++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
index fd2a0ed21165..6307d0261ceb 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -530,6 +530,46 @@ int serial8250_request_dma(struct uart_8250_port *p)
}
EXPORT_SYMBOL_GPL(serial8250_request_dma);
+static void serial8250_terminate_dma(struct uart_8250_port *p)
+{
+ struct uart_8250_dma *dma = p->dma;
+ unsigned int delay_us = USEC_PER_MSEC;
+ ktime_t start;
+ int rx_ret, tx_ret;
+
+ rx_ret = dmaengine_terminate_sync(dma->rxchan);
+ tx_ret = dmaengine_terminate_sync(dma->txchan);
+ if (!rx_ret && !tx_ret)
+ return;
+
+ start = ktime_get();
+ dev_err(p->port.dev,
+ "DMA termination failed: RX %d, TX %d; teardown blocked\n",
+ rx_ret, tx_ret);
+
+ /*
+ * Shutdown cannot return while DMA owns storage or callback state:
+ * serial core frees the TX FIFO afterwards, and removal frees the port.
+ * Retain both channels and retry outside the port lock. A permanently
+ * failed DMA engine therefore prevents teardown from completing.
+ */
+ while (rx_ret || tx_ret) {
+ fsleep(delay_us);
+ /* Retry promptly at first, then limit sustained retry activity. */
+ delay_us = min(delay_us * 2, USEC_PER_SEC);
+ if (rx_ret)
+ rx_ret = dmaengine_terminate_sync(dma->rxchan);
+ if (tx_ret)
+ tx_ret = dmaengine_terminate_sync(dma->txchan);
+ if (rx_ret || tx_ret)
+ dev_err_ratelimited(p->port.dev,
+ "DMA termination still failing after %lld ms: RX %d, TX %d\n",
+ ktime_ms_delta(ktime_get(), start), rx_ret, tx_ret);
+ }
+ dev_info(p->port.dev, "DMA termination recovered after %lld ms\n",
+ ktime_ms_delta(ktime_get(), start));
+}
+
void serial8250_release_dma(struct uart_8250_port *p)
{
struct uart_8250_dma *dma = p->dma;
@@ -539,9 +579,9 @@ void serial8250_release_dma(struct uart_8250_port *p)
cancel_work_sync(&dma->tx_flush_work);
cancel_work_sync(&dma->rx_flush_work);
+ serial8250_terminate_dma(p);
/* Release RX resources */
- dmaengine_terminate_sync(dma->rxchan);
scoped_guard(uart_port_lock_irqsave, &p->port) {
dma->rx_running = 0;
dma->rx_terminating = false;
@@ -553,7 +593,6 @@ void serial8250_release_dma(struct uart_8250_port *p)
dma->rxchan = NULL;
/* Release TX resources */
- dmaengine_terminate_sync(dma->txchan);
dma_unmap_single(dmaengine_get_dma_device(dma->txchan), dma->tx_addr,
UART_XMIT_SIZE, DMA_TO_DEVICE);
dma_release_channel(dma->txchan);
--
2.53.0
prev parent reply other threads:[~2026-11-02 23:14 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 23:14 [PATCH v9 0/8] serial: 8250: serialize DMA cancellation with buffer reuse James Hilliard
2026-11-02 23:14 ` [PATCH v9 1/8] serial: 8250_omap: separate locked TX DMA completion processing James Hilliard
2026-11-02 23:14 ` [PATCH v9 2/8] serial: serialize asynchronous write wakeups with the port lock James Hilliard
2026-11-02 23:14 ` [PATCH v9 3/8] serial: 8250_omap: serialize RX DMA completion and flushing James Hilliard
2026-11-03 11:55 ` Ilpo Järvinen
2026-11-02 23:14 ` [PATCH v9 4/8] serial: 8250_omap: quiesce DMA IRQ handling before shutdown James Hilliard
2026-11-02 23:14 ` [PATCH v9 5/8] serial: core: allow drivers to reserve flushed transmit storage James Hilliard
2026-11-02 23:14 ` [PATCH v9 6/8] serial: 8250: drain canceled TX DMA before reusing its buffer James Hilliard
2026-11-02 23:14 ` [PATCH v9 7/8] serial: 8250: retire canceled RX DMA before reusing the receive buffer James Hilliard
2026-11-02 23:14 ` James Hilliard [this message]
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=20261102-submit-serial-8250-dma-cancel-v1-v9-8-9159caade148@gmail.com \
--to=james.hilliard1@gmail.com \
--cc=Frank.Li@nxp.com \
--cc=alexandre.belloni@bootlin.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bigeasy@linutronix.de \
--cc=claudiu.beznea@tuxon.dev \
--cc=festevam@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=imx@lists.linux.dev \
--cc=jirislaby@kernel.org \
--cc=kernel@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=macro@orcam.me.uk \
--cc=nicolas.ferre@microchip.com \
--cc=pali@kernel.org \
--cc=patrice.chotard@foss.st.com \
--cc=peter.ujfalusi@ti.com \
--cc=richard.genoud@bootlin.com \
--cc=rrangel@chromium.org \
--cc=s.hauer@pengutronix.de \
--cc=schung@nuvoton.com \
--cc=timur@kernel.org \
--cc=tony@atomide.com \
--cc=vigneshr@ti.com \
--cc=ychuang3@nuvoton.com \
/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
all inboxes | Powered by JetHome®