mirror-linux/drivers/tty/serial/8250
John Keeping 9e512eaaf8 serial: 8250: Fix fifo underflow on flush
When flushing the serial port's buffer, uart_flush_buffer() calls
kfifo_reset() but if there is an outstanding DMA transfer then the
completion function will consume data from the kfifo via
uart_xmit_advance(), underflowing and leading to ongoing DMA as the
driver tries to transmit another 2^32 bytes.

This is readily reproduced with serial-generic and amidi sending even
short messages as closing the device on exit will wait for the fifo to
drain and in the underflow case amidi hangs for 30 seconds on exit in
tty_wait_until_sent().  A trace of that gives:

     kworker/1:1-84    [001]    51.769423: bprint:               serial8250_tx_dma: tx_size=3 fifo_len=3
           amidi-763   [001]    51.769460: bprint:               uart_flush_buffer: resetting fifo
 irq/21-fe530000-76    [000]    51.769474: bprint:               __dma_tx_complete: tx_size=3
 irq/21-fe530000-76    [000]    51.769479: bprint:               serial8250_tx_dma: tx_size=4096 fifo_len=4294967293
 irq/21-fe530000-76    [000]    51.781295: bprint:               __dma_tx_complete: tx_size=4096
 irq/21-fe530000-76    [000]    51.781301: bprint:               serial8250_tx_dma: tx_size=4096 fifo_len=4294963197
 irq/21-fe530000-76    [000]    51.793131: bprint:               __dma_tx_complete: tx_size=4096
 irq/21-fe530000-76    [000]    51.793135: bprint:               serial8250_tx_dma: tx_size=4096 fifo_len=4294959101
 irq/21-fe530000-76    [000]    51.804949: bprint:               __dma_tx_complete: tx_size=4096

Since the port lock is held in when the kfifo is reset in
uart_flush_buffer() and in __dma_tx_complete(), adding a flush_buffer
hook to adjust the outstanding DMA byte count is sufficient to avoid the
kfifo underflow.

Fixes: 9ee4b83e51 ("serial: 8250: Add support for dmaengine")
Cc: stable <stable@kernel.org>
Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
Link: https://lore.kernel.org/r/20250208124148.1189191-1-jkeeping@inmusicbrands.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2025-02-14 09:50:55 +01:00
..
8250.h serial: 8250: Fix fifo underflow on flush 2025-02-14 09:50:55 +01:00
8250_accent.c
8250_acorn.c
8250_aspeed_vuart.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_bcm2835aux.c serial: 8250: Provide flag for IER toggling for RS485 2025-01-10 16:08:25 +01:00
8250_bcm7271.c serial: 8250: Fix typos in comments across various files 2024-10-11 08:14:50 +02:00
8250_boca.c
8250_core.c Revert "serial: 8250: Switch to nbcon console" 2025-01-22 10:35:56 +01:00
8250_dfl.c
8250_dma.c serial: 8250: Fix fifo underflow on flush 2025-02-14 09:50:55 +01:00
8250_dw.c serial: 8250_dw: Add Sophgo SG2044 quirk 2024-11-04 02:02:21 +01:00
8250_dwlib.c serial: remove quot_frac from serial8250_do_set_divisor() 2024-08-07 13:13:35 +02:00
8250_dwlib.h serial: 8250_dw: Revert "Move definitions to the shared header" 2024-06-04 14:07:58 +02:00
8250_early.c tty: serial: handle HAS_IOPORT dependencies 2024-10-28 21:44:28 +00:00
8250_em.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_exar.c module: Convert symbol namespace to string literal 2024-12-02 11:34:44 -08:00
8250_exar_st16c554.c
8250_fintek.c serial: 8250_fintek: Add support for F81216E 2024-11-12 13:05:38 +01:00
8250_fourport.c
8250_fsl.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_hp300.c
8250_hub6.c
8250_ingenic.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_ioc3.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_lpc18xx.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_lpss.c serial: 8250_lpss: copy dma_param using devm_kmemdup() 2024-01-04 16:21:51 +01:00
8250_men_mcb.c module: Convert symbol namespace to string literal 2024-12-02 11:34:44 -08:00
8250_mid.c serial: 8250_mid: Remove 8250_pci usage 2023-09-18 11:14:43 +02:00
8250_mtk.c serial: 8250: Fix typos in comments across various files 2024-10-11 08:14:50 +02:00
8250_of.c serial: 8250_of: Remove unneeded ->iotype assignment 2025-02-04 14:44:50 +01:00
8250_omap.c serial: 8250: Provide flag for IER toggling for RS485 2025-01-10 16:08:25 +01:00
8250_parisc.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00
8250_pci.c serial: 8250_pci: Share WCH IDs with parport_serial driver 2024-12-04 16:42:55 +01:00
8250_pci1xxxx.c 8250: microchip: pci1xxxx: Add workaround for RTS bit toggle 2024-12-23 18:59:44 +01:00
8250_pcilib.c module: Convert symbol namespace to string literal 2024-12-02 11:34:44 -08:00
8250_pcilib.h tty: serial: handle HAS_IOPORT dependencies 2024-10-28 21:44:28 +00:00
8250_pericom.c
8250_platform.c serial: 8250_platform: Remove unneeded ->iotype assignment 2025-02-04 14:44:52 +01:00
8250_pnp.c serial: 8250_pnp: Remove unneeded ->iotype assignment 2025-02-04 14:44:53 +01:00
8250_port.c serial: 8250: Fix fifo underflow on flush 2025-02-14 09:50:55 +01:00
8250_pxa.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_rsa.c serial: 8250: Extract RSA bits 2024-06-04 14:01:50 +02:00
8250_rt288x.c
8250_tegra.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
8250_uniphier.c serial: Switch back to struct platform_driver::remove() 2024-10-11 08:13:28 +02:00
Kconfig TTY / Serial driver updates for 6.13-rc1 2024-11-30 09:03:16 -08:00
Makefile serial: 8250: Extract platform driver 2024-06-04 14:01:50 +02:00
serial_cs.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00