summaryrefslogtreecommitdiff
path: root/drivers/cpufreq/longhaul.h
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2019-06-24 14:35:39 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-07-03 19:31:30 +0200
commit8493eab02608b0e82f67b892aa72882e510c31d0 (patch)
tree82c4b069ab8eb51f666b4560fce687d70d376281 /drivers/cpufreq/longhaul.h
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 <erosca@de.adit-jv.com> Suggested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Eugeniu Rosca <erosca@de.adit-jv.com> Tested-by: Eugeniu Rosca <erosca@de.adit-jv.com> Link: https://lore.kernel.org/r/20190624123540.20629-2-geert+renesas@glider.be Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/cpufreq/longhaul.h')
0 files changed, 0 insertions, 0 deletions