aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGeert Uytterhoeven <[email protected]>2019-06-24 14:35:39 +0200
committerGreg Kroah-Hartman <[email protected]>2019-07-03 19:31:30 +0200
commit8493eab02608b0e82f67b892aa72882e510c31d0 (patch)
tree82c4b069ab8eb51f666b4560fce687d70d376281 /lib
parentecd6bf67da3126e8ec731c2dd8cb6c2f17d9563a (diff)
serial: sh-sci: Fix TX DMA buffer flushing and workqueue races
When uart_flush_buffer() is called, the .flush_buffer() callback zeroes the tx_dma_len field. This may race with the work queue function handling transmit DMA requests: 1. If the buffer is flushed before the first DMA API call, dmaengine_prep_slave_single() may be called with a zero length, causing the DMA request to never complete, leading to messages like: rcar-dmac e7300000.dma-controller: Channel Address Error happen and, with debug enabled: sh-sci e6e88000.serial: sci_dma_tx_work_fn: ffff800639b55000: 0...0, cookie 126 and DMA timeouts. 2. If the buffer is flushed after the first DMA API call, but before the second, dma_sync_single_for_device() may be called with a zero length, causing the transmit data not to be flushed to RAM, and leading to stale data being output. Fix this by: 1. Letting sci_dma_tx_work_fn() return immediately if the transmit buffer is empty, 2. Extending the critical section to cover all DMA preparational work, so tx_dma_len stays consistent for all of it, 3. Using local copies of circ_buf.head and circ_buf.tail, to make sure they match the actual operation above. Reported-by: Eugeniu Rosca <[email protected]> Suggested-by: Yoshihiro Shimoda <[email protected]> Signed-off-by: Geert Uytterhoeven <[email protected]> Reviewed-by: Eugeniu Rosca <[email protected]> Tested-by: Eugeniu Rosca <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
Diffstat (limited to 'lib')
0 files changed, 0 insertions, 0 deletions